/openid-connect-server/src/main/java/org/mitre/openid/connect/web/UserInfoEndpoint.java
Java | 142 lines | 84 code | 24 blank | 34 comment | 24 complexity | 34c5204b83a23e87bb0788dc05c7db37 MD5 | raw file
- /*******************************************************************************
- * Copyright 2016 The MITRE Corporation
- * and the MIT Internet Trust Consortium
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *******************************************************************************/
- package org.mitre.openid.connect.web;
- import java.util.List;
- import org.mitre.oauth2.model.ClientDetailsEntity;
- import org.mitre.oauth2.service.ClientDetailsEntityService;
- import org.mitre.oauth2.service.SystemScopeService;
- import org.mitre.openid.connect.model.UserInfo;
- import org.mitre.openid.connect.service.UserInfoService;
- import org.mitre.openid.connect.view.HttpCodeView;
- import org.mitre.openid.connect.view.UserInfoJWTView;
- import org.mitre.openid.connect.view.UserInfoView;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.HttpStatus;
- import org.springframework.http.MediaType;
- import org.springframework.security.access.prepost.PreAuthorize;
- import org.springframework.security.oauth2.provider.OAuth2Authentication;
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.Model;
- import org.springframework.web.bind.annotation.RequestHeader;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.bind.annotation.RequestParam;
- import com.google.common.base.Strings;
- /**
- * OpenID Connect UserInfo endpoint, as specified in Standard sec 5 and Messages sec 2.4.
- *
- * @author AANGANES
- *
- */
- @Controller
- @RequestMapping("/" + UserInfoEndpoint.URL)
- public class UserInfoEndpoint {
- public static final String URL = "userinfo";
- @Autowired
- private UserInfoService userInfoService;
- @Autowired
- private ClientDetailsEntityService clientService;
- /**
- * Logger for this class
- */
- private static final Logger logger = LoggerFactory.getLogger(UserInfoEndpoint.class);
- /**
- * Get information about the user as specified in the accessToken included in this request
- */
- @PreAuthorize("hasRole('ROLE_USER') and #oauth2.hasScope('" + SystemScopeService.OPENID_SCOPE + "')")
- @RequestMapping(method= {RequestMethod.GET, RequestMethod.POST}, produces = {MediaType.APPLICATION_JSON_VALUE, UserInfoJWTView.JOSE_MEDIA_TYPE_VALUE})
- public String getInfo(@RequestParam(value="claims", required=false) String claimsRequestJsonString,
- @RequestHeader(value=HttpHeaders.ACCEPT, required=false) String acceptHeader,
- OAuth2Authentication auth, Model model) {
- if (auth == null) {
- logger.error("getInfo failed; no principal. Requester is not authorized.");
- model.addAttribute(HttpCodeView.CODE, HttpStatus.FORBIDDEN);
- return HttpCodeView.VIEWNAME;
- }
- String username = auth.getName();
- UserInfo userInfo = userInfoService.getByUsernameAndClientId(username, auth.getOAuth2Request().getClientId());
- if (userInfo == null) {
- logger.error("getInfo failed; user not found: " + username);
- model.addAttribute(HttpCodeView.CODE, HttpStatus.NOT_FOUND);
- return HttpCodeView.VIEWNAME;
- }
- model.addAttribute(UserInfoView.SCOPE, auth.getOAuth2Request().getScope());
- model.addAttribute(UserInfoView.AUTHORIZED_CLAIMS, auth.getOAuth2Request().getExtensions().get("claims"));
- if (!Strings.isNullOrEmpty(claimsRequestJsonString)) {
- model.addAttribute(UserInfoView.REQUESTED_CLAIMS, claimsRequestJsonString);
- }
- model.addAttribute(UserInfoView.USER_INFO, userInfo);
- // content negotiation
- // start off by seeing if the client has registered for a signed/encrypted JWT from here
- ClientDetailsEntity client = clientService.loadClientByClientId(auth.getOAuth2Request().getClientId());
- model.addAttribute(UserInfoJWTView.CLIENT, client);
- List<MediaType> mediaTypes = MediaType.parseMediaTypes(acceptHeader);
- MediaType.sortBySpecificityAndQuality(mediaTypes);
- if (client.getUserInfoSignedResponseAlg() != null
- || client.getUserInfoEncryptedResponseAlg() != null
- || client.getUserInfoEncryptedResponseEnc() != null) {
- // client has a preference, see if they ask for plain JSON specifically on this request
- for (MediaType m : mediaTypes) {
- if (!m.isWildcardType() && m.isCompatibleWith(UserInfoJWTView.JOSE_MEDIA_TYPE)) {
- return UserInfoJWTView.VIEWNAME;
- } else if (!m.isWildcardType() && m.isCompatibleWith(MediaType.APPLICATION_JSON)) {
- return UserInfoView.VIEWNAME;
- }
- }
- // otherwise return JWT
- return UserInfoJWTView.VIEWNAME;
- } else {
- // client has no preference, see if they asked for JWT specifically on this request
- for (MediaType m : mediaTypes) {
- if (!m.isWildcardType() && m.isCompatibleWith(MediaType.APPLICATION_JSON)) {
- return UserInfoView.VIEWNAME;
- } else if (!m.isWildcardType() && m.isCompatibleWith(UserInfoJWTView.JOSE_MEDIA_TYPE)) {
- return UserInfoJWTView.VIEWNAME;
- }
- }
- // otherwise return JSON
- return UserInfoView.VIEWNAME;
- }
- }
- }