|  | @ -0,0 +1,699 @@
 | 
	
		
			
				|  |  | package com.yihu.jw.security.oauth2.provider.endpoint;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | import com.yihu.jw.security.core.userdetails.jdbc.WlyyUserDetailsService;
 | 
	
		
			
				|  |  | import com.yihu.jw.security.oauth2.provider.client.WlyyJdbcClientRedirectUriService;
 | 
	
		
			
				|  |  | import com.yihu.utils.network.IPInfoUtils;
 | 
	
		
			
				|  |  | import org.slf4j.Logger;
 | 
	
		
			
				|  |  | import org.slf4j.LoggerFactory;
 | 
	
		
			
				|  |  | import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  | import org.springframework.http.ResponseEntity;
 | 
	
		
			
				|  |  | import org.springframework.security.access.AccessDeniedException;
 | 
	
		
			
				|  |  | import org.springframework.security.authentication.InsufficientAuthenticationException;
 | 
	
		
			
				|  |  | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 | 
	
		
			
				|  |  | import org.springframework.security.core.Authentication;
 | 
	
		
			
				|  |  | import org.springframework.security.core.AuthenticationException;
 | 
	
		
			
				|  |  | import org.springframework.security.core.context.SecurityContext;
 | 
	
		
			
				|  |  | import org.springframework.security.core.context.SecurityContextHolder;
 | 
	
		
			
				|  |  | import org.springframework.security.core.context.SecurityContextHolderStrategy;
 | 
	
		
			
				|  |  | import org.springframework.security.core.userdetails.UserDetails;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.common.OAuth2AccessToken;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.common.exceptions.*;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.common.util.OAuth2Utils;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerEndpointsConfiguration;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.provider.*;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.provider.approval.DefaultUserApprovalHandler;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.provider.endpoint.*;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.provider.implicit.ImplicitTokenRequest;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestValidator;
 | 
	
		
			
				|  |  | import org.springframework.security.oauth2.provider.token.TokenStore;
 | 
	
		
			
				|  |  | import org.springframework.stereotype.Controller;
 | 
	
		
			
				|  |  | import org.springframework.util.StringUtils;
 | 
	
		
			
				|  |  | import org.springframework.web.HttpSessionRequiredException;
 | 
	
		
			
				|  |  | import org.springframework.web.bind.annotation.*;
 | 
	
		
			
				|  |  | import org.springframework.web.bind.support.DefaultSessionAttributeStore;
 | 
	
		
			
				|  |  | import org.springframework.web.bind.support.SessionAttributeStore;
 | 
	
		
			
				|  |  | import org.springframework.web.bind.support.SessionStatus;
 | 
	
		
			
				|  |  | import org.springframework.web.context.request.RequestContextHolder;
 | 
	
		
			
				|  |  | import org.springframework.web.context.request.ServletRequestAttributes;
 | 
	
		
			
				|  |  | import org.springframework.web.context.request.ServletWebRequest;
 | 
	
		
			
				|  |  | import org.springframework.web.servlet.ModelAndView;
 | 
	
		
			
				|  |  | import org.springframework.web.servlet.View;
 | 
	
		
			
				|  |  | import org.springframework.web.servlet.view.RedirectView;
 | 
	
		
			
				|  |  | import org.springframework.web.util.UriComponents;
 | 
	
		
			
				|  |  | import org.springframework.web.util.UriComponentsBuilder;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | import javax.annotation.PostConstruct;
 | 
	
		
			
				|  |  | import javax.servlet.http.HttpServletRequest;
 | 
	
		
			
				|  |  | import java.net.URI;
 | 
	
		
			
				|  |  | import java.security.Principal;
 | 
	
		
			
				|  |  | import java.util.*;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  | /**
 | 
	
		
			
				|  |  |  * authorization_code & implicit & sso Endpoint
 | 
	
		
			
				|  |  |  *
 | 
	
		
			
				|  |  |  * <p>
 | 
	
		
			
				|  |  |  * Implementation of the Authorization Endpoint from the OAuth2 specification. Accepts authorization requests, and
 | 
	
		
			
				|  |  |  * handles user approval if the grant type is authorization code. The tokens themselves are obtained from the
 | 
	
		
			
				|  |  |  * {@link WlyyTokenEndpoint Token Endpoint}, except in the implicit grant type (where they come from the Authorization
 | 
	
		
			
				|  |  |  * Endpoint via <code>response_type=token</code>.
 | 
	
		
			
				|  |  |  * {@link WlyyLoginEndpoint Login Endpoint}, in order to verify the token to obtain user information.
 | 
	
		
			
				|  |  |  *
 | 
	
		
			
				|  |  |  * </p>
 | 
	
		
			
				|  |  |  *
 | 
	
		
			
				|  |  |  * <p>
 | 
	
		
			
				|  |  |  * This endpoint should be secured so that it is only accessible to fully authenticated users (as a minimum requirement)
 | 
	
		
			
				|  |  |  * since it represents a request from a valid user to act on his or her behalf.
 | 
	
		
			
				|  |  |  * </p>
 | 
	
		
			
				|  |  |  *
 | 
	
		
			
				|  |  |  * @author Progr1mmer
 | 
	
		
			
				|  |  |  * @created on 2018/8/29.
 | 
	
		
			
				|  |  |  */
 | 
	
		
			
				|  |  | @Controller
 | 
	
		
			
				|  |  | @SessionAttributes("authorizationRequest")
 | 
	
		
			
				|  |  | public class WlyyAuthorizationEndpoint extends AbstractEndpoint {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private final Logger LOG = LoggerFactory.getLogger(getClass());
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private AuthorizationCodeServices authorizationCodeServices = new InMemoryAuthorizationCodeServices();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private RedirectResolver redirectResolver = new DefaultRedirectResolver();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private UserApprovalHandler userApprovalHandler = new DefaultUserApprovalHandler();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private SessionAttributeStore sessionAttributeStore = new DefaultSessionAttributeStore();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private OAuth2RequestValidator oauth2RequestValidator = new DefaultOAuth2RequestValidator();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private String userApprovalPage = "forward:/oauth/confirm_access";
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private String errorPage = "forward:/oauth/error";
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private Object implicitLock = new Object();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private TokenStore tokenStore;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private WlyyUserDetailsService userDetailsService;
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private AuthorizationServerEndpointsConfiguration authorizationServerEndpointsConfiguration;
 | 
	
		
			
				|  |  |     @Autowired
 | 
	
		
			
				|  |  |     private WlyyJdbcClientRedirectUriService wlyyJdbcClientRedirectUriService;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @PostConstruct
 | 
	
		
			
				|  |  |     private void init() {
 | 
	
		
			
				|  |  |         AuthorizationServerEndpointsConfigurer authorizationServerEndpointsConfigurer = authorizationServerEndpointsConfiguration.getEndpointsConfigurer();
 | 
	
		
			
				|  |  |         super.setTokenGranter(authorizationServerEndpointsConfigurer.getTokenGranter());
 | 
	
		
			
				|  |  |         super.setClientDetailsService(authorizationServerEndpointsConfigurer.getClientDetailsService());
 | 
	
		
			
				|  |  |         this.tokenStore = authorizationServerEndpointsConfigurer.getTokenStore();
 | 
	
		
			
				|  |  |         this.authorizationCodeServices = authorizationServerEndpointsConfigurer.getAuthorizationCodeServices();
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public void setSessionAttributeStore(SessionAttributeStore sessionAttributeStore) {
 | 
	
		
			
				|  |  |         this.sessionAttributeStore = sessionAttributeStore;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public void setErrorPage(String errorPage) {
 | 
	
		
			
				|  |  |         this.errorPage = errorPage;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @RequestMapping(value = "/oauth/authorize", method = RequestMethod.GET)
 | 
	
		
			
				|  |  |     public ModelAndView authorize(Map<String, Object> model, @RequestParam Map<String, String> parameters,
 | 
	
		
			
				|  |  |                                   SessionStatus sessionStatus, Principal principal) {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         // Pull out the authorization request first, using the OAuth2RequestFactory. All further logic should
 | 
	
		
			
				|  |  |         // query off of the authorization request instead of referring back to the parameters map. The contents of the
 | 
	
		
			
				|  |  |         // parameters map will be stored without change in the AuthorizationRequest object once it is created.
 | 
	
		
			
				|  |  |         AuthorizationRequest authorizationRequest = getOAuth2RequestFactory().createAuthorizationRequest(parameters);
 | 
	
		
			
				|  |  |         /* default approve */
 | 
	
		
			
				|  |  |         authorizationRequest.setApproved(true);
 | 
	
		
			
				|  |  |         Set<String> responseTypes = authorizationRequest.getResponseTypes();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (!responseTypes.contains("token") && !responseTypes.contains("code")) {
 | 
	
		
			
				|  |  |             throw new UnsupportedResponseTypeException("Unsupported response types: " + responseTypes);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (authorizationRequest.getClientId() == null) {
 | 
	
		
			
				|  |  |             throw new InvalidClientException("A client id must be provided");
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         try {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             if (!(principal instanceof Authentication) || !((Authentication) principal).isAuthenticated()) {
 | 
	
		
			
				|  |  |                 if (parameters.containsKey("ak")) {
 | 
	
		
			
				|  |  |                     String ak = parameters.get("ak");
 | 
	
		
			
				|  |  |                     UsernamePasswordAuthenticationToken userAuth = new UsernamePasswordAuthenticationToken("admin", "cdb7df66a1955b0ed7402e665ed0586a", new ArrayList<>());
 | 
	
		
			
				|  |  |                     SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
 | 
	
		
			
				|  |  |                     securityContext.setAuthentication(userAuth);
 | 
	
		
			
				|  |  |                     SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder.getContextHolderStrategy();
 | 
	
		
			
				|  |  |                     securityContextHolderStrategy.setContext(securityContext);
 | 
	
		
			
				|  |  |                     principal = userAuth;
 | 
	
		
			
				|  |  |                 } else {
 | 
	
		
			
				|  |  |                     throw new InsufficientAuthenticationException("ak must be provided.");
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             /*if (!(principal instanceof Authentication) || !((Authentication) principal).isAuthenticated()) {
 | 
	
		
			
				|  |  |                 throw new InsufficientAuthenticationException(
 | 
	
		
			
				|  |  |                         "User must be authenticated with Spring Security before authorization can be completed.");
 | 
	
		
			
				|  |  |             }*/
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             ClientDetails client = getClientDetailsService().loadClientByClientId(authorizationRequest.getClientId());
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // The resolved redirect URI is either the redirect_uri from the parameters or the one from
 | 
	
		
			
				|  |  |             // clientDetails. Either way we need to store it on the AuthorizationRequest.
 | 
	
		
			
				|  |  |             String redirectUriParameter = authorizationRequest.getRequestParameters().get(OAuth2Utils.REDIRECT_URI);
 | 
	
		
			
				|  |  |             String validUrl = wlyyJdbcClientRedirectUriService.loadValidUri(authorizationRequest.getClientId(), redirectUriParameter);
 | 
	
		
			
				|  |  |             String resolvedRedirect = redirectResolver.resolveRedirect(validUrl, client);
 | 
	
		
			
				|  |  |             if (!StringUtils.hasText(resolvedRedirect)) {
 | 
	
		
			
				|  |  |                 throw new RedirectMismatchException(
 | 
	
		
			
				|  |  |                         "A redirectUri must be either supplied or preconfigured in the ClientDetails");
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // (customize) If redirectUriParameter is empty
 | 
	
		
			
				|  |  |             // load internal and external network ip information to redirect
 | 
	
		
			
				|  |  |             String accessUri = wlyyJdbcClientRedirectUriService.loadAccessUri(authorizationRequest.getClientId(), redirectUriParameter);
 | 
	
		
			
				|  |  |             authorizationRequest.setRedirectUri(accessUri);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // We intentionally only validate the parameters requested by the client (ignoring any data that may have
 | 
	
		
			
				|  |  |             // been added to the request by the manager).
 | 
	
		
			
				|  |  |             oauth2RequestValidator.validateScope(authorizationRequest, client);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // Some systems may allow for approval decisions to be remembered or approved by default. Check for
 | 
	
		
			
				|  |  |             // such logic here, and set the approved flag on the authorization request accordingly.
 | 
	
		
			
				|  |  |             authorizationRequest = userApprovalHandler.checkForPreApproval(authorizationRequest,
 | 
	
		
			
				|  |  |                     (Authentication) principal);
 | 
	
		
			
				|  |  |             // TODO: is this call necessary?
 | 
	
		
			
				|  |  |             boolean approved = userApprovalHandler.isApproved(authorizationRequest, (Authentication) principal);
 | 
	
		
			
				|  |  |             authorizationRequest.setApproved(approved);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // Validation is all done, so we can check for auto approval...
 | 
	
		
			
				|  |  |             if (authorizationRequest.isApproved()) {
 | 
	
		
			
				|  |  |                 if (responseTypes.contains("token")) {
 | 
	
		
			
				|  |  |                     return getImplicitGrantResponse(authorizationRequest);
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |                 if (responseTypes.contains("code")) {
 | 
	
		
			
				|  |  |                     return new ModelAndView(getAuthorizationCodeResponse(authorizationRequest,
 | 
	
		
			
				|  |  |                             (Authentication) principal));
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // Place auth request into the model so that it is stored in the session
 | 
	
		
			
				|  |  |             // for approveOrDeny to use. That way we make sure that auth request comes from the session,
 | 
	
		
			
				|  |  |             // so any auth request parameters passed to approveOrDeny will be ignored and retrieved from the session.
 | 
	
		
			
				|  |  |             model.put("authorizationRequest", authorizationRequest);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             return getUserApprovalPageResponse(model, authorizationRequest, (Authentication) principal);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         } catch (RuntimeException e) {
 | 
	
		
			
				|  |  |             sessionStatus.setComplete();
 | 
	
		
			
				|  |  |             throw e;
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @RequestMapping(value = "/oauth/authorize", method = RequestMethod.POST, params = OAuth2Utils.USER_OAUTH_APPROVAL)
 | 
	
		
			
				|  |  |     public View approveOrDeny(@RequestParam Map<String, String> approvalParameters, Map<String, ?> model,
 | 
	
		
			
				|  |  |                               SessionStatus sessionStatus, Principal principal) {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (!(principal instanceof Authentication)) {
 | 
	
		
			
				|  |  |             sessionStatus.setComplete();
 | 
	
		
			
				|  |  |             throw new InsufficientAuthenticationException(
 | 
	
		
			
				|  |  |                     "User must be authenticated with Spring Security before authorizing an access token.");
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         AuthorizationRequest authorizationRequest = (AuthorizationRequest) model.get("authorizationRequest");
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (authorizationRequest == null) {
 | 
	
		
			
				|  |  |             sessionStatus.setComplete();
 | 
	
		
			
				|  |  |             throw new InvalidRequestException("Cannot approve uninitialized authorization request.");
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         try {
 | 
	
		
			
				|  |  |             Set<String> responseTypes = authorizationRequest.getResponseTypes();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             authorizationRequest.setApprovalParameters(approvalParameters);
 | 
	
		
			
				|  |  |             authorizationRequest = userApprovalHandler.updateAfterApproval(authorizationRequest,
 | 
	
		
			
				|  |  |                     (Authentication) principal);
 | 
	
		
			
				|  |  |             boolean approved = userApprovalHandler.isApproved(authorizationRequest, (Authentication) principal);
 | 
	
		
			
				|  |  |             authorizationRequest.setApproved(approved);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             if (authorizationRequest.getRedirectUri() == null) {
 | 
	
		
			
				|  |  |                 sessionStatus.setComplete();
 | 
	
		
			
				|  |  |                 throw new InvalidRequestException("Cannot approve request when no redirect URI is provided.");
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             if (!authorizationRequest.isApproved()) {
 | 
	
		
			
				|  |  |                 return new RedirectView(getUnsuccessfulRedirect(authorizationRequest,
 | 
	
		
			
				|  |  |                         new UserDeniedAuthorizationException("User denied access"), responseTypes.contains("token")),
 | 
	
		
			
				|  |  |                         false, true, false);
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             if (responseTypes.contains("token")) {
 | 
	
		
			
				|  |  |                 return getImplicitGrantResponse(authorizationRequest).getView();
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             return getAuthorizationCodeResponse(authorizationRequest, (Authentication) principal);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         finally {
 | 
	
		
			
				|  |  |             sessionStatus.setComplete();
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @RequestMapping(value = "/oauth/sso", method = RequestMethod.GET)
 | 
	
		
			
				|  |  |     public ModelAndView sso(Map<String, Object> model, @RequestParam Map<String, String> parameters,
 | 
	
		
			
				|  |  |                                   SessionStatus sessionStatus, Principal principal) {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         // Pull out the authorization request first, using the OAuth2RequestFactory. All further logic should
 | 
	
		
			
				|  |  |         // query off of the authorization request instead of referring back to the parameters map. The contents of the
 | 
	
		
			
				|  |  |         // parameters map will be stored without change in the AuthorizationRequest object once it is created.
 | 
	
		
			
				|  |  |         AuthorizationRequest authorizationRequest = getOAuth2RequestFactory().createAuthorizationRequest(parameters);
 | 
	
		
			
				|  |  |         /* default approve */
 | 
	
		
			
				|  |  |         authorizationRequest.setApproved(true);
 | 
	
		
			
				|  |  |         Set<String> responseTypes = authorizationRequest.getResponseTypes();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         /* Does not accept code type verification */
 | 
	
		
			
				|  |  |         if (!responseTypes.contains("token")) {
 | 
	
		
			
				|  |  |             throw new UnsupportedResponseTypeException("Unsupported response types: " + responseTypes);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         /*if (!responseTypes.contains("token") && !responseTypes.contains("code")) {
 | 
	
		
			
				|  |  |             throw new UnsupportedResponseTypeException("Unsupported response types: " + responseTypes);
 | 
	
		
			
				|  |  |         }*/
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (authorizationRequest.getClientId() == null) {
 | 
	
		
			
				|  |  |             throw new InvalidClientException("A client id must be provided");
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         try {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             /*
 | 
	
		
			
				|  |  |              * load verification information by token
 | 
	
		
			
				|  |  |              */
 | 
	
		
			
				|  |  |             if (!(principal instanceof Authentication) || !((Authentication) principal).isAuthenticated()) {
 | 
	
		
			
				|  |  |                 if (parameters.containsKey("access_token")) {
 | 
	
		
			
				|  |  |                     String token = parameters.get("access_token");
 | 
	
		
			
				|  |  |                     OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token);
 | 
	
		
			
				|  |  |                     if (null == oAuth2AccessToken) {
 | 
	
		
			
				|  |  |                         throw new InvalidTokenException("Invalid access_token");
 | 
	
		
			
				|  |  |                     }
 | 
	
		
			
				|  |  |                     if (oAuth2AccessToken.isExpired()) {
 | 
	
		
			
				|  |  |                         throw new InvalidTokenException("Expired accessToken");
 | 
	
		
			
				|  |  |                     }
 | 
	
		
			
				|  |  |                     OAuth2Authentication authentication = tokenStore.readAuthentication(token);
 | 
	
		
			
				|  |  |                     if (authentication != null) {
 | 
	
		
			
				|  |  |                         String userName = authentication.getName();
 | 
	
		
			
				|  |  |                         UserDetails userDetails = userDetailsService.loadUserByUsername(userName);
 | 
	
		
			
				|  |  |                         UsernamePasswordAuthenticationToken userAuth = new UsernamePasswordAuthenticationToken(userDetails.getUsername(), userDetails.getPassword(), userDetails.getAuthorities());
 | 
	
		
			
				|  |  |                         SecurityContext securityContext = SecurityContextHolder.createEmptyContext();
 | 
	
		
			
				|  |  |                         securityContext.setAuthentication(userAuth);
 | 
	
		
			
				|  |  |                         SecurityContextHolderStrategy securityContextHolderStrategy = SecurityContextHolder.getContextHolderStrategy();
 | 
	
		
			
				|  |  |                         securityContextHolderStrategy.setContext(securityContext);
 | 
	
		
			
				|  |  |                         principal = userAuth;
 | 
	
		
			
				|  |  |                     } else {
 | 
	
		
			
				|  |  |                         throw new InvalidTokenException("Cant not load authentication");
 | 
	
		
			
				|  |  |                     }
 | 
	
		
			
				|  |  |                 } else {
 | 
	
		
			
				|  |  |                     throw new InvalidRequestException("access_token must be provided.");
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             ClientDetails client = getClientDetailsService().loadClientByClientId(authorizationRequest.getClientId());
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // The resolved redirect URI is either the redirect_uri from the parameters or the one from
 | 
	
		
			
				|  |  |             // clientDetails. Either way we need to store it on the AuthorizationRequest.
 | 
	
		
			
				|  |  |             String redirectUriParameter = authorizationRequest.getRequestParameters().get(OAuth2Utils.REDIRECT_URI);
 | 
	
		
			
				|  |  |             String validUrl = wlyyJdbcClientRedirectUriService.loadValidUri(authorizationRequest.getClientId(), redirectUriParameter);
 | 
	
		
			
				|  |  |             String resolvedRedirect = redirectResolver.resolveRedirect(validUrl, client);
 | 
	
		
			
				|  |  |             if (!StringUtils.hasText(resolvedRedirect)) {
 | 
	
		
			
				|  |  |                 throw new RedirectMismatchException(
 | 
	
		
			
				|  |  |                         "A redirectUri must be either supplied or preconfigured in the ClientDetails");
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // (customize) If redirectUriParameter is empty
 | 
	
		
			
				|  |  |             // load internal and external network ip information to redirect
 | 
	
		
			
				|  |  |             String accessUri = wlyyJdbcClientRedirectUriService.loadAccessUri(authorizationRequest.getClientId(), redirectUriParameter);
 | 
	
		
			
				|  |  |             authorizationRequest.setRedirectUri(accessUri);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // We intentionally only validate the parameters requested by the client (ignoring any data that may have
 | 
	
		
			
				|  |  |             // been added to the request by the manager).
 | 
	
		
			
				|  |  |             oauth2RequestValidator.validateScope(authorizationRequest, client);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // Some systems may allow for approval decisions to be remembered or approved by default. Check for
 | 
	
		
			
				|  |  |             // such logic here, and set the approved flag on the authorization request accordingly.
 | 
	
		
			
				|  |  |             authorizationRequest = userApprovalHandler.checkForPreApproval(authorizationRequest,
 | 
	
		
			
				|  |  |                     (Authentication) principal);
 | 
	
		
			
				|  |  |             // TODO: is this call necessary?
 | 
	
		
			
				|  |  |             boolean approved = userApprovalHandler.isApproved(authorizationRequest, (Authentication) principal);
 | 
	
		
			
				|  |  |             authorizationRequest.setApproved(approved);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // Validation is all done, so we can check for auto approval...
 | 
	
		
			
				|  |  |             if (authorizationRequest.isApproved()) {
 | 
	
		
			
				|  |  |                 if (responseTypes.contains("token")) {
 | 
	
		
			
				|  |  |                     return getImplicitGrantResponse(authorizationRequest);
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |                 if (responseTypes.contains("code")) {
 | 
	
		
			
				|  |  |                     return new ModelAndView(getAuthorizationCodeResponse(authorizationRequest,
 | 
	
		
			
				|  |  |                             (Authentication) principal));
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             // Place auth request into the model so that it is stored in the session
 | 
	
		
			
				|  |  |             // for approveOrDeny to use. That way we make sure that auth request comes from the session,
 | 
	
		
			
				|  |  |             // so any auth request parameters passed to approveOrDeny will be ignored and retrieved from the session.
 | 
	
		
			
				|  |  |             model.put("authorizationRequest", authorizationRequest);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             return getUserApprovalPageResponse(model, authorizationRequest, (Authentication) principal);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         } catch (RuntimeException e) {
 | 
	
		
			
				|  |  |             sessionStatus.setComplete();
 | 
	
		
			
				|  |  |             throw e;
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     // We need explicit approval from the user.
 | 
	
		
			
				|  |  |     private ModelAndView getUserApprovalPageResponse(Map<String, Object> model,
 | 
	
		
			
				|  |  |                                                      AuthorizationRequest authorizationRequest, Authentication principal) {
 | 
	
		
			
				|  |  |         LOG.debug("Loading user approval page: " + userApprovalPage);
 | 
	
		
			
				|  |  |         model.putAll(userApprovalHandler.getUserApprovalRequest(authorizationRequest, principal));
 | 
	
		
			
				|  |  |         return new ModelAndView(userApprovalPage, model);
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     // We can grant a token and return it with implicit approval.
 | 
	
		
			
				|  |  |     private ModelAndView getImplicitGrantResponse(AuthorizationRequest authorizationRequest) {
 | 
	
		
			
				|  |  |         try {
 | 
	
		
			
				|  |  |             TokenRequest tokenRequest = getOAuth2RequestFactory().createTokenRequest(authorizationRequest, "implicit");
 | 
	
		
			
				|  |  |             OAuth2Request storedOAuth2Request = getOAuth2RequestFactory().createOAuth2Request(authorizationRequest);
 | 
	
		
			
				|  |  |             OAuth2AccessToken accessToken = getAccessTokenForImplicitGrant(tokenRequest, storedOAuth2Request);
 | 
	
		
			
				|  |  |             if (accessToken == null) {
 | 
	
		
			
				|  |  |                 throw new UnsupportedResponseTypeException("Unsupported response type: token");
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |             return new ModelAndView(new RedirectView(appendAccessToken(authorizationRequest, accessToken), false, true,
 | 
	
		
			
				|  |  |                     false));
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         catch (OAuth2Exception e) {
 | 
	
		
			
				|  |  |             return new ModelAndView(new RedirectView(getUnsuccessfulRedirect(authorizationRequest, e, true), false,
 | 
	
		
			
				|  |  |                     true, false));
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private OAuth2AccessToken getAccessTokenForImplicitGrant(TokenRequest tokenRequest,
 | 
	
		
			
				|  |  |                                                              OAuth2Request storedOAuth2Request) {
 | 
	
		
			
				|  |  |         OAuth2AccessToken accessToken = null;
 | 
	
		
			
				|  |  |         // These 1 method calls have to be atomic, otherwise the ImplicitGrantService can have a race condition where
 | 
	
		
			
				|  |  |         // one thread removes the token request before another has a chance to redeem it.
 | 
	
		
			
				|  |  |         synchronized (this.implicitLock) {
 | 
	
		
			
				|  |  |             accessToken = getTokenGranter().grant("implicit",
 | 
	
		
			
				|  |  |                     new ImplicitTokenRequest(tokenRequest, storedOAuth2Request));
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         return accessToken;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private View getAuthorizationCodeResponse(AuthorizationRequest authorizationRequest, Authentication authUser) {
 | 
	
		
			
				|  |  |         try {
 | 
	
		
			
				|  |  |             return new RedirectView(getSuccessfulRedirect(authorizationRequest,
 | 
	
		
			
				|  |  |                     generateCode(authorizationRequest, authUser)), false, true, false);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         catch (OAuth2Exception e) {
 | 
	
		
			
				|  |  |             return new RedirectView(getUnsuccessfulRedirect(authorizationRequest, e, false), false, true, false);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private String appendAccessToken(AuthorizationRequest authorizationRequest, OAuth2AccessToken accessToken) {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         Map<String, Object> vars = new LinkedHashMap<String, Object>();
 | 
	
		
			
				|  |  |         Map<String, String> keys = new HashMap<String, String>();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (accessToken == null) {
 | 
	
		
			
				|  |  |             throw new InvalidRequestException("An implicit grant could not be made");
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         vars.put("accessToken", accessToken.getValue());
 | 
	
		
			
				|  |  |         vars.put("tokenType", accessToken.getTokenType());
 | 
	
		
			
				|  |  |         String state = authorizationRequest.getState();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (state != null) {
 | 
	
		
			
				|  |  |             vars.put("state", state);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         Date expiration = accessToken.getExpiration();
 | 
	
		
			
				|  |  |         if (expiration != null) {
 | 
	
		
			
				|  |  |             long expires_in = (expiration.getTime() - System.currentTimeMillis()) / 1000;
 | 
	
		
			
				|  |  |             vars.put("expiresIn", expires_in);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         String originalScope = authorizationRequest.getRequestParameters().get(OAuth2Utils.SCOPE);
 | 
	
		
			
				|  |  |         if (originalScope == null || !OAuth2Utils.parseParameterList(originalScope).equals(accessToken.getScope())) {
 | 
	
		
			
				|  |  |             vars.put("scope", OAuth2Utils.formatParameterList(accessToken.getScope()));
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         Map<String, Object> additionalInformation = accessToken.getAdditionalInformation();
 | 
	
		
			
				|  |  |         for (String key : additionalInformation.keySet()) {
 | 
	
		
			
				|  |  |             Object value = additionalInformation.get(key);
 | 
	
		
			
				|  |  |             if (value != null) {
 | 
	
		
			
				|  |  |                 keys.put("extra_" + key, key);
 | 
	
		
			
				|  |  |                 vars.put("extra_" + key, value);
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         // Do not include the refresh token (even if there is one)
 | 
	
		
			
				|  |  |         return append(authorizationRequest.getRedirectUri(), vars, keys, true);
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private String generateCode(AuthorizationRequest authorizationRequest, Authentication authentication)
 | 
	
		
			
				|  |  |             throws AuthenticationException {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         try {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             OAuth2Request storedOAuth2Request = getOAuth2RequestFactory().createOAuth2Request(authorizationRequest);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             OAuth2Authentication combinedAuth = new OAuth2Authentication(storedOAuth2Request, authentication);
 | 
	
		
			
				|  |  |             String code = authorizationCodeServices.createAuthorizationCode(combinedAuth);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             return code;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         catch (OAuth2Exception e) {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             if (authorizationRequest.getState() != null) {
 | 
	
		
			
				|  |  |                 e.addAdditionalInformation("state", authorizationRequest.getState());
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |             throw e;
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private String getSuccessfulRedirect(AuthorizationRequest authorizationRequest, String authorizationCode) {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (authorizationCode == null) {
 | 
	
		
			
				|  |  |             throw new IllegalStateException("No authorization code found in the current request scope.");
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         Map<String, String> query = new LinkedHashMap<String, String>();
 | 
	
		
			
				|  |  |         query.put("code", authorizationCode);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         String state = authorizationRequest.getState();
 | 
	
		
			
				|  |  |         if (state != null) {
 | 
	
		
			
				|  |  |             query.put("state", state);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         return append(authorizationRequest.getRedirectUri(), query, false);
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private String getUnsuccessfulRedirect(AuthorizationRequest authorizationRequest, OAuth2Exception failure,
 | 
	
		
			
				|  |  |                                            boolean fragment) {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (authorizationRequest == null || authorizationRequest.getRedirectUri() == null) {
 | 
	
		
			
				|  |  |             // we have no redirect for the user. very sad.
 | 
	
		
			
				|  |  |             throw new UnapprovedClientAuthenticationException("Authorization failure, and no redirect URI.", failure);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         Map<String, String> query = new LinkedHashMap<String, String>();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         query.put("error", failure.getOAuth2ErrorCode());
 | 
	
		
			
				|  |  |         query.put("error_description", failure.getMessage());
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (authorizationRequest.getState() != null) {
 | 
	
		
			
				|  |  |             query.put("state", authorizationRequest.getState());
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (failure.getAdditionalInformation() != null) {
 | 
	
		
			
				|  |  |             for (Map.Entry<String, String> additionalInfo : failure.getAdditionalInformation().entrySet()) {
 | 
	
		
			
				|  |  |                 query.put(additionalInfo.getKey(), additionalInfo.getValue());
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         return append(authorizationRequest.getRedirectUri(), query, fragment);
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private String append(String base, Map<String, ?> query, boolean fragment) {
 | 
	
		
			
				|  |  |         return append(base, query, null, fragment);
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private String append(String base, Map<String, ?> query, Map<String, String> keys, boolean fragment) {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         UriComponentsBuilder template = UriComponentsBuilder.newInstance();
 | 
	
		
			
				|  |  |         UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(base);
 | 
	
		
			
				|  |  |         URI redirectUri;
 | 
	
		
			
				|  |  |         try {
 | 
	
		
			
				|  |  |             // assume it's encoded to start with (if it came in over the wire)
 | 
	
		
			
				|  |  |             redirectUri = builder.build(true).toUri();
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         catch (Exception e) {
 | 
	
		
			
				|  |  |             // ... but allow client registrations to contain hard-coded non-encoded values
 | 
	
		
			
				|  |  |             redirectUri = builder.build().toUri();
 | 
	
		
			
				|  |  |             builder = UriComponentsBuilder.fromUri(redirectUri);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         template.scheme(redirectUri.getScheme()).port(redirectUri.getPort()).host(redirectUri.getHost())
 | 
	
		
			
				|  |  |                 .userInfo(redirectUri.getUserInfo()).path(redirectUri.getPath());
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (fragment) {
 | 
	
		
			
				|  |  |             StringBuilder values = new StringBuilder();
 | 
	
		
			
				|  |  |             if (redirectUri.getFragment() != null) {
 | 
	
		
			
				|  |  |                 String append = redirectUri.getFragment();
 | 
	
		
			
				|  |  |                 values.append(append);
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |             for (String key : query.keySet()) {
 | 
	
		
			
				|  |  |                 if (values.length() > 0) {
 | 
	
		
			
				|  |  |                     values.append("&");
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |                 String name = key;
 | 
	
		
			
				|  |  |                 if (keys != null && keys.containsKey(key)) {
 | 
	
		
			
				|  |  |                     name = keys.get(key);
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |                 values.append(name + "={" + key + "}");
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |             if (values.length() > 0) {
 | 
	
		
			
				|  |  |                 template.fragment(values.toString());
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |             UriComponents encoded = template.build().expand(query).encode();
 | 
	
		
			
				|  |  |             builder.fragment(encoded.getFragment());
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         else {
 | 
	
		
			
				|  |  |             for (String key : query.keySet()) {
 | 
	
		
			
				|  |  |                 String name = key;
 | 
	
		
			
				|  |  |                 if (keys != null && keys.containsKey(key)) {
 | 
	
		
			
				|  |  |                     name = keys.get(key);
 | 
	
		
			
				|  |  |                 }
 | 
	
		
			
				|  |  |                 template.queryParam(name, "{" + key + "}");
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |             template.fragment(redirectUri.getFragment());
 | 
	
		
			
				|  |  |             UriComponents encoded = template.build().expand(query).encode();
 | 
	
		
			
				|  |  |             builder.query(encoded.getQuery());
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         return builder.build().toUriString();
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public void setUserApprovalPage(String userApprovalPage) {
 | 
	
		
			
				|  |  |         this.userApprovalPage = userApprovalPage;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public void setAuthorizationCodeServices(AuthorizationCodeServices authorizationCodeServices) {
 | 
	
		
			
				|  |  |         this.authorizationCodeServices = authorizationCodeServices;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public void setRedirectResolver(RedirectResolver redirectResolver) {
 | 
	
		
			
				|  |  |         this.redirectResolver = redirectResolver;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public void setUserApprovalHandler(UserApprovalHandler userApprovalHandler) {
 | 
	
		
			
				|  |  |         this.userApprovalHandler = userApprovalHandler;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     public void setOAuth2RequestValidator(OAuth2RequestValidator oauth2RequestValidator) {
 | 
	
		
			
				|  |  |         this.oauth2RequestValidator = oauth2RequestValidator;
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @SuppressWarnings("deprecation")
 | 
	
		
			
				|  |  |     public void setImplicitGrantService(
 | 
	
		
			
				|  |  |             org.springframework.security.oauth2.provider.implicit.ImplicitGrantService implicitGrantService) {
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @ExceptionHandler(Exception.class)
 | 
	
		
			
				|  |  |     public ModelAndView handleGlobalException(Exception e) throws Exception {
 | 
	
		
			
				|  |  |         LOG.info(e.getMessage(), e);
 | 
	
		
			
				|  |  |         return new ModelAndView(errorPage, Collections.singletonMap("error", new OAuth2Exception(e.getMessage(), e)));
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     /*@ExceptionHandler(ClientRegistrationException.class)
 | 
	
		
			
				|  |  |     public ModelAndView handleClientRegistrationException(Exception e, ServletWebRequest webRequest) throws Exception {
 | 
	
		
			
				|  |  |         LOG.info("Handling ClientRegistrationException error: " + e.getMessage());
 | 
	
		
			
				|  |  |         return handleException(new BadClientCredentialsException(), webRequest);
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @ExceptionHandler(OAuth2Exception.class)
 | 
	
		
			
				|  |  |     public ModelAndView handleOAuth2Exception(OAuth2Exception e, ServletWebRequest webRequest) throws Exception {
 | 
	
		
			
				|  |  |         LOG.info("Handling OAuth2 error: " + e.getSummary());
 | 
	
		
			
				|  |  |         return handleException(e, webRequest);
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     @ExceptionHandler(HttpSessionRequiredException.class)
 | 
	
		
			
				|  |  |     public ModelAndView handleHttpSessionRequiredException(HttpSessionRequiredException e, ServletWebRequest webRequest)
 | 
	
		
			
				|  |  |             throws Exception {
 | 
	
		
			
				|  |  |         LOG.info("Handling Session required error: " + e.getMessage());
 | 
	
		
			
				|  |  |         return handleException(new AccessDeniedException("Could not obtain authorization request from session", e),
 | 
	
		
			
				|  |  |                 webRequest);
 | 
	
		
			
				|  |  |     }*/
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private ModelAndView handleException(Exception e, ServletWebRequest webRequest) throws Exception {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         ResponseEntity<OAuth2Exception> translate = getExceptionTranslator().translate(e);
 | 
	
		
			
				|  |  |         webRequest.getResponse().setStatus(translate.getStatusCode().value());
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         if (e instanceof ClientAuthenticationException || e instanceof RedirectMismatchException) {
 | 
	
		
			
				|  |  |             return new ModelAndView(errorPage, Collections.singletonMap("error", translate.getBody()));
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         AuthorizationRequest authorizationRequest = null;
 | 
	
		
			
				|  |  |         try {
 | 
	
		
			
				|  |  |             authorizationRequest = getAuthorizationRequestForError(webRequest);
 | 
	
		
			
				|  |  |             String requestedRedirectParam = authorizationRequest.getRequestParameters().get(OAuth2Utils.REDIRECT_URI);
 | 
	
		
			
				|  |  |             String requestedRedirect = redirectResolver.resolveRedirect(requestedRedirectParam,
 | 
	
		
			
				|  |  |                     getClientDetailsService().loadClientByClientId(authorizationRequest.getClientId()));
 | 
	
		
			
				|  |  |             authorizationRequest.setRedirectUri(requestedRedirect);
 | 
	
		
			
				|  |  |             String redirect = getUnsuccessfulRedirect(authorizationRequest, translate.getBody(), authorizationRequest
 | 
	
		
			
				|  |  |                     .getResponseTypes().contains("token"));
 | 
	
		
			
				|  |  |             return new ModelAndView(new RedirectView(redirect, false, true, false));
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         catch (OAuth2Exception ex) {
 | 
	
		
			
				|  |  |             // If an AuthorizationRequest cannot be created from the incoming parameters it must be
 | 
	
		
			
				|  |  |             // an error. OAuth2Exception can be handled this way. Other exceptions will generate a standard 500
 | 
	
		
			
				|  |  |             // response.
 | 
	
		
			
				|  |  |             return new ModelAndView(errorPage, Collections.singletonMap("error", translate.getBody()));
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     private AuthorizationRequest getAuthorizationRequestForError(ServletWebRequest webRequest) {
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         // If it's already there then we are in the approveOrDeny phase and we can use the saved request
 | 
	
		
			
				|  |  |         AuthorizationRequest authorizationRequest = (AuthorizationRequest) sessionAttributeStore.retrieveAttribute(
 | 
	
		
			
				|  |  |                 webRequest, "authorizationRequest");
 | 
	
		
			
				|  |  |         if (authorizationRequest != null) {
 | 
	
		
			
				|  |  |             return authorizationRequest;
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         Map<String, String> parameters = new HashMap<String, String>();
 | 
	
		
			
				|  |  |         Map<String, String[]> map = webRequest.getParameterMap();
 | 
	
		
			
				|  |  |         for (String key : map.keySet()) {
 | 
	
		
			
				|  |  |             String[] values = map.get(key);
 | 
	
		
			
				|  |  |             if (values != null && values.length > 0) {
 | 
	
		
			
				|  |  |                 parameters.put(key, values[0]);
 | 
	
		
			
				|  |  |             }
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |         try {
 | 
	
		
			
				|  |  |             return getOAuth2RequestFactory().createAuthorizationRequest(parameters);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  |         catch (Exception e) {
 | 
	
		
			
				|  |  |             return getDefaultOAuth2RequestFactory().createAuthorizationRequest(parameters);
 | 
	
		
			
				|  |  |         }
 | 
	
		
			
				|  |  | 
 | 
	
		
			
				|  |  |     }
 | 
	
		
			
				|  |  | }
 |