/oauth2/rest_token impl
							parent
							
								
									df8113d18a
								
							
						
					
					
						commit
						beac2d1f00
					
				|  | @ -53,7 +53,7 @@ public class WebSecurityConfigurer { | |||
|         http.authorizeHttpRequests(matcherRegistry -> { | ||||
|             // permitAll() 的URL路径属于公开访问,不需要权限
 | ||||
|             matcherRegistry | ||||
|                     .requestMatchers("/favicon.ico*", "/oauth/rest_token*", "*.js", "*.css").permitAll() | ||||
|                     .requestMatchers("/favicon.ico*", "/oauth2/rest_token*", "*.js", "*.css").permitAll() | ||||
|                     .requestMatchers("/api/public/**").permitAll() | ||||
|                     .requestMatchers(HttpMethod.GET, "/login*").anonymous() | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,22 @@ | |||
| package com.monkeyk.sos.web.authentication; | ||||
| 
 | ||||
| import org.springframework.security.oauth2.core.OAuth2AuthenticationException; | ||||
| import org.springframework.security.oauth2.core.OAuth2Error; | ||||
| 
 | ||||
| /** | ||||
|  * 2023/10/31 10:35 | ||||
|  * | ||||
|  * @author Shengzhao Li | ||||
|  * @since 3.0.0 | ||||
|  */ | ||||
| public abstract class AbstractAuthenticationRestConverter implements AuthenticationRestConverter { | ||||
| 
 | ||||
|     static final String ACCESS_TOKEN_REQUEST_ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"; | ||||
| 
 | ||||
| 
 | ||||
|     protected void throwError(String errorCode, String parameterName, String errorUri) { | ||||
|         OAuth2Error error = new OAuth2Error(errorCode, "OAuth 2.0 Parameter: " + parameterName, errorUri); | ||||
|         throw new OAuth2AuthenticationException(error); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,24 @@ | |||
| package com.monkeyk.sos.web.authentication; | ||||
| 
 | ||||
| import org.springframework.security.core.Authentication; | ||||
| 
 | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 2023/10/31 10:27 | ||||
|  * | ||||
|  * @author Shengzhao Li | ||||
|  * @see org.springframework.security.web.authentication.AuthenticationConverter | ||||
|  * @since 3.0.0 | ||||
|  */ | ||||
| public interface AuthenticationRestConverter { | ||||
| 
 | ||||
|     /** | ||||
|      * 从请求参数中转化到  Authentication | ||||
|      * | ||||
|      * @param parameters 请求参数 | ||||
|      * @return Authentication or null | ||||
|      */ | ||||
|     Authentication convert(Map<String, String> parameters); | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,45 @@ | |||
| package com.monkeyk.sos.web.authentication; | ||||
| 
 | ||||
| import org.springframework.security.core.Authentication; | ||||
| import org.springframework.security.web.authentication.AuthenticationConverter; | ||||
| import org.springframework.util.Assert; | ||||
| 
 | ||||
| import java.util.Collections; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 2023/10/31 10:30 | ||||
|  * | ||||
|  * @author Shengzhao Li | ||||
|  * @see org.springframework.security.oauth2.server.authorization.web.authentication.DelegatingAuthenticationConverter | ||||
|  * @since 3.0.0 | ||||
|  */ | ||||
| public final class DelegatingAuthenticationRestConverter implements AuthenticationRestConverter { | ||||
| 
 | ||||
|     private final List<AuthenticationRestConverter> converters; | ||||
| 
 | ||||
|     /** | ||||
|      * Constructs a {@code DelegatingAuthenticationConverter} using the provided parameters. | ||||
|      * | ||||
|      * @param converters a {@code List} of {@link AuthenticationConverter}(s) | ||||
|      */ | ||||
|     public DelegatingAuthenticationRestConverter(List<AuthenticationRestConverter> converters) { | ||||
|         Assert.notEmpty(converters, "converters cannot be empty"); | ||||
|         this.converters = Collections.unmodifiableList(new LinkedList<>(converters)); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public Authentication convert(Map<String, String> parameters) { | ||||
|         Assert.notNull(parameters, "parameters cannot be null"); | ||||
|         for (AuthenticationRestConverter converter : this.converters) { | ||||
|             Authentication authentication = converter.convert(parameters); | ||||
|             if (authentication != null) { | ||||
|                 return authentication; | ||||
|             } | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,69 @@ | |||
| package com.monkeyk.sos.web.authentication; | ||||
| 
 | ||||
| import org.springframework.security.core.Authentication; | ||||
| import org.springframework.security.core.context.SecurityContextHolder; | ||||
| import org.springframework.security.oauth2.core.AuthorizationGrantType; | ||||
| import org.springframework.security.oauth2.core.OAuth2ErrorCodes; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; | ||||
| import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeAuthenticationToken; | ||||
| import org.springframework.util.StringUtils; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 2023/10/31 10:33 | ||||
|  * | ||||
|  * @author Shengzhao Li | ||||
|  * @see org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2AuthorizationCodeAuthenticationConverter | ||||
|  * @since 3.0.0 | ||||
|  */ | ||||
| public final class OAuth2AuthorizationCodeAuthenticationRestConverter extends AbstractAuthenticationRestConverter { | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public Authentication convert(Map<String, String> parameters) { | ||||
|         // grant_type (REQUIRED)
 | ||||
|         String grantType = parameters.get(OAuth2ParameterNames.GRANT_TYPE); | ||||
|         if (!AuthorizationGrantType.AUTHORIZATION_CODE.getValue().equals(grantType)) { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         Authentication clientPrincipal = SecurityContextHolder.getContext().getAuthentication(); | ||||
| 
 | ||||
| //        MultiValueMap<String, String> parameters = OAuth2EndpointUtils.getParameters(request);
 | ||||
| 
 | ||||
|         // code (REQUIRED)
 | ||||
|         String code = parameters.get(OAuth2ParameterNames.CODE); | ||||
|         if (!StringUtils.hasText(code)) { | ||||
|             throwError( | ||||
|                     OAuth2ErrorCodes.INVALID_REQUEST, | ||||
|                     OAuth2ParameterNames.CODE, | ||||
|                     ACCESS_TOKEN_REQUEST_ERROR_URI); | ||||
|         } | ||||
| 
 | ||||
|         // redirect_uri (REQUIRED)
 | ||||
|         // Required only if the "redirect_uri" parameter was included in the authorization request
 | ||||
|         String redirectUri = parameters.get(OAuth2ParameterNames.REDIRECT_URI); | ||||
|         if (!StringUtils.hasText(redirectUri)) { | ||||
|             throwError( | ||||
|                     OAuth2ErrorCodes.INVALID_REQUEST, | ||||
|                     OAuth2ParameterNames.REDIRECT_URI, | ||||
|                     ACCESS_TOKEN_REQUEST_ERROR_URI); | ||||
|         } | ||||
| 
 | ||||
|         Map<String, Object> additionalParameters = new HashMap<>(); | ||||
|         parameters.forEach((key, value) -> { | ||||
|             if (!key.equals(OAuth2ParameterNames.GRANT_TYPE) && | ||||
|                     !key.equals(OAuth2ParameterNames.CLIENT_ID) && | ||||
|                     !key.equals(OAuth2ParameterNames.CODE) && | ||||
|                     !key.equals(OAuth2ParameterNames.REDIRECT_URI)) { | ||||
| //                additionalParameters.put(key, (value.size() == 1) ? value.get(0) : value.toArray(new String[0]));
 | ||||
|                 additionalParameters.put(key, value); | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         return new OAuth2AuthorizationCodeAuthenticationToken( | ||||
|                 code, clientPrincipal, redirectUri, additionalParameters); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,60 @@ | |||
| package com.monkeyk.sos.web.authentication; | ||||
| 
 | ||||
| import org.springframework.security.core.Authentication; | ||||
| import org.springframework.security.core.context.SecurityContextHolder; | ||||
| import org.springframework.security.oauth2.core.AuthorizationGrantType; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; | ||||
| import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientCredentialsAuthenticationToken; | ||||
| import org.springframework.util.StringUtils; | ||||
| 
 | ||||
| import java.util.*; | ||||
| 
 | ||||
| /** | ||||
|  * 2023/10/31 10:33 | ||||
|  * | ||||
|  * @author Shengzhao Li | ||||
|  * @see org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2ClientCredentialsAuthenticationConverter | ||||
|  * @since 3.0.0 | ||||
|  */ | ||||
| public final class OAuth2ClientCredentialsAuthenticationRestConverter extends AbstractAuthenticationRestConverter { | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public Authentication convert(Map<String, String> parameters) { | ||||
|         // grant_type (REQUIRED)
 | ||||
|         String grantType = parameters.get(OAuth2ParameterNames.GRANT_TYPE); | ||||
|         if (!AuthorizationGrantType.CLIENT_CREDENTIALS.getValue().equals(grantType)) { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         Authentication clientPrincipal = SecurityContextHolder.getContext().getAuthentication(); | ||||
| 
 | ||||
| //        MultiValueMap<String, String> parameters = OAuth2EndpointUtils.getParameters(request);
 | ||||
| 
 | ||||
|         // scope (OPTIONAL)
 | ||||
|         String scope = parameters.get(OAuth2ParameterNames.SCOPE); | ||||
| //        if (StringUtils.hasText(scope) &&
 | ||||
| //                parameters.get(OAuth2ParameterNames.SCOPE).size() != 1) {
 | ||||
| //            throwError(
 | ||||
| //                    OAuth2ErrorCodes.INVALID_REQUEST,
 | ||||
| //                    OAuth2ParameterNames.SCOPE,
 | ||||
| //                    ACCESS_TOKEN_REQUEST_ERROR_URI);
 | ||||
| //        }
 | ||||
|         Set<String> requestedScopes = null; | ||||
|         if (StringUtils.hasText(scope)) { | ||||
|             requestedScopes = new HashSet<>( | ||||
|                     Arrays.asList(StringUtils.delimitedListToStringArray(scope, " "))); | ||||
|         } | ||||
| 
 | ||||
|         Map<String, Object> additionalParameters = new HashMap<>(); | ||||
|         parameters.forEach((key, value) -> { | ||||
|             if (!key.equals(OAuth2ParameterNames.GRANT_TYPE) && | ||||
|                     !key.equals(OAuth2ParameterNames.SCOPE)) { | ||||
|                 additionalParameters.put(key, value); | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         return new OAuth2ClientCredentialsAuthenticationToken( | ||||
|                 clientPrincipal, requestedScopes, additionalParameters); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,56 @@ | |||
| package com.monkeyk.sos.web.authentication; | ||||
| 
 | ||||
| import org.springframework.security.core.Authentication; | ||||
| import org.springframework.security.core.context.SecurityContextHolder; | ||||
| import org.springframework.security.oauth2.core.AuthorizationGrantType; | ||||
| import org.springframework.security.oauth2.core.OAuth2ErrorCodes; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; | ||||
| import org.springframework.security.oauth2.server.authorization.authentication.OAuth2DeviceCodeAuthenticationToken; | ||||
| import org.springframework.util.StringUtils; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  * 2023/10/31 10:33 | ||||
|  * | ||||
|  * @author Shengzhao Li | ||||
|  * @see org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2DeviceCodeAuthenticationConverter | ||||
|  * @since 3.0.0 | ||||
|  */ | ||||
| public final class OAuth2DeviceCodeAuthenticationRestConverter extends AbstractAuthenticationRestConverter { | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public Authentication convert(Map<String, String> parameters) { | ||||
|         // grant_type (REQUIRED)
 | ||||
|         String grantType = parameters.get(OAuth2ParameterNames.GRANT_TYPE); | ||||
|         if (!AuthorizationGrantType.DEVICE_CODE.getValue().equals(grantType)) { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         Authentication clientPrincipal = SecurityContextHolder.getContext().getAuthentication(); | ||||
| 
 | ||||
| //        MultiValueMap<String, String> parameters = OAuth2EndpointUtils.getParameters(request);
 | ||||
| 
 | ||||
|         // device_code (REQUIRED)
 | ||||
|         String deviceCode = parameters.get(OAuth2ParameterNames.DEVICE_CODE); | ||||
|         if (!StringUtils.hasText(deviceCode)) { | ||||
|             throwError( | ||||
|                     OAuth2ErrorCodes.INVALID_REQUEST, | ||||
|                     OAuth2ParameterNames.DEVICE_CODE, | ||||
|                     ACCESS_TOKEN_REQUEST_ERROR_URI); | ||||
|         } | ||||
| 
 | ||||
|         Map<String, Object> additionalParameters = new HashMap<>(); | ||||
|         parameters.forEach((key, value) -> { | ||||
|             if (!key.equals(OAuth2ParameterNames.GRANT_TYPE) && | ||||
|                     !key.equals(OAuth2ParameterNames.CLIENT_ID) && | ||||
|                     !key.equals(OAuth2ParameterNames.DEVICE_CODE)) { | ||||
|                 additionalParameters.put(key, value); | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         return new OAuth2DeviceCodeAuthenticationToken(deviceCode, clientPrincipal, additionalParameters); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,70 @@ | |||
| package com.monkeyk.sos.web.authentication; | ||||
| 
 | ||||
| import org.springframework.security.core.Authentication; | ||||
| import org.springframework.security.core.context.SecurityContextHolder; | ||||
| import org.springframework.security.oauth2.core.AuthorizationGrantType; | ||||
| import org.springframework.security.oauth2.core.OAuth2ErrorCodes; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; | ||||
| import org.springframework.security.oauth2.server.authorization.authentication.OAuth2RefreshTokenAuthenticationToken; | ||||
| import org.springframework.util.StringUtils; | ||||
| 
 | ||||
| import java.util.*; | ||||
| 
 | ||||
| /** | ||||
|  * 2023/10/31 10:33 | ||||
|  * | ||||
|  * @author Shengzhao Li | ||||
|  * @see org.springframework.security.oauth2.server.authorization.web.authentication.OAuth2RefreshTokenAuthenticationConverter | ||||
|  * @since 3.0.0 | ||||
|  */ | ||||
| public final class OAuth2RefreshTokenAuthenticationRestConverter extends AbstractAuthenticationRestConverter { | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public Authentication convert(Map<String, String> parameters) { | ||||
|         // grant_type (REQUIRED)
 | ||||
|         String grantType = parameters.get(OAuth2ParameterNames.GRANT_TYPE); | ||||
|         if (!AuthorizationGrantType.REFRESH_TOKEN.getValue().equals(grantType)) { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         Authentication clientPrincipal = SecurityContextHolder.getContext().getAuthentication(); | ||||
| 
 | ||||
| //        MultiValueMap<String, String> parameters = OAuth2EndpointUtils.getParameters(request);
 | ||||
| 
 | ||||
|         // refresh_token (REQUIRED)
 | ||||
|         String refreshToken = parameters.get(OAuth2ParameterNames.REFRESH_TOKEN); | ||||
|         if (!StringUtils.hasText(refreshToken)) { | ||||
|             throwError( | ||||
|                     OAuth2ErrorCodes.INVALID_REQUEST, | ||||
|                     OAuth2ParameterNames.REFRESH_TOKEN, | ||||
|                     ACCESS_TOKEN_REQUEST_ERROR_URI); | ||||
|         } | ||||
| 
 | ||||
|         // scope (OPTIONAL)
 | ||||
|         String scope = parameters.get(OAuth2ParameterNames.SCOPE); | ||||
| //        if (!StringUtils.hasText(scope)) {
 | ||||
| //            throwError(
 | ||||
| //                    OAuth2ErrorCodes.INVALID_REQUEST,
 | ||||
| //                    OAuth2ParameterNames.SCOPE,
 | ||||
| //                    ACCESS_TOKEN_REQUEST_ERROR_URI);
 | ||||
| //        }
 | ||||
|         Set<String> requestedScopes = null; | ||||
|         if (StringUtils.hasText(scope)) { | ||||
|             requestedScopes = new HashSet<>( | ||||
|                     Arrays.asList(StringUtils.delimitedListToStringArray(scope, " "))); | ||||
|         } | ||||
| 
 | ||||
|         Map<String, Object> additionalParameters = new HashMap<>(); | ||||
|         parameters.forEach((key, value) -> { | ||||
|             if (!key.equals(OAuth2ParameterNames.GRANT_TYPE) && | ||||
|                     !key.equals(OAuth2ParameterNames.REFRESH_TOKEN) && | ||||
|                     !key.equals(OAuth2ParameterNames.SCOPE)) { | ||||
|                 additionalParameters.put(key, value); | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
|         return new OAuth2RefreshTokenAuthenticationToken( | ||||
|                 refreshToken, clientPrincipal, requestedScopes, additionalParameters); | ||||
|     } | ||||
| } | ||||
|  | @ -11,23 +11,38 @@ | |||
|  */ | ||||
| package com.monkeyk.sos.web.controller; | ||||
| 
 | ||||
| import com.monkeyk.sos.web.WebUtils; | ||||
| import com.monkeyk.sos.web.authentication.*; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springframework.beans.BeansException; | ||||
| import org.springframework.beans.factory.InitializingBean; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.context.ApplicationContext; | ||||
| import org.springframework.context.ApplicationContextAware; | ||||
| import org.springframework.http.HttpStatus; | ||||
| import org.springframework.http.converter.HttpMessageConverter; | ||||
| import org.springframework.http.server.ServletServerHttpResponse; | ||||
| import org.springframework.security.authentication.AbstractAuthenticationToken; | ||||
| import org.springframework.security.authentication.AuthenticationManager; | ||||
| import org.springframework.security.crypto.password.PasswordEncoder; | ||||
| import org.springframework.security.oauth2.core.OAuth2AccessToken; | ||||
| import org.springframework.security.core.Authentication; | ||||
| import org.springframework.security.core.AuthenticationException; | ||||
| import org.springframework.security.core.context.SecurityContextHolder; | ||||
| import org.springframework.security.oauth2.core.*; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; | ||||
| import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; | ||||
| import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter; | ||||
| import org.springframework.security.oauth2.core.http.converter.OAuth2ErrorHttpMessageConverter; | ||||
| import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AccessTokenAuthenticationToken; | ||||
| import org.springframework.security.web.authentication.WebAuthenticationDetails; | ||||
| import org.springframework.stereotype.Controller; | ||||
| import org.springframework.util.Assert; | ||||
| import org.springframework.web.bind.annotation.RequestBody; | ||||
| import org.springframework.web.bind.annotation.RequestMapping; | ||||
| import org.springframework.web.bind.annotation.RequestMethod; | ||||
| import org.springframework.web.bind.annotation.ResponseBody; | ||||
| import org.springframework.util.CollectionUtils; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.time.temporal.ChronoUnit; | ||||
| import java.util.Arrays; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| /** | ||||
|  | @ -45,165 +60,115 @@ public class OAuthRestController implements InitializingBean, ApplicationContext | |||
| 
 | ||||
|     private static final Logger LOG = LoggerFactory.getLogger(OAuthRestController.class); | ||||
| 
 | ||||
| //    @Autowired
 | ||||
| //    private ClientDetailsService clientDetailsService;
 | ||||
| //
 | ||||
| //    // consumerTokenServices,defaultAuthorizationServerTokenServices
 | ||||
| //    @Autowired
 | ||||
| //    @Qualifier("defaultAuthorizationServerTokenServices")
 | ||||
| //    private AuthorizationServerTokenServices tokenServices;
 | ||||
| //    @Autowired
 | ||||
| //    private AuthorizationCodeServices authorizationCodeServices;
 | ||||
| 
 | ||||
|     @Autowired | ||||
|     private PasswordEncoder passwordEncoder; | ||||
| 
 | ||||
| //    private AuthenticationManager authenticationManager;
 | ||||
| 
 | ||||
| //    private OAuth2RequestFactory oAuth2RequestFactory;
 | ||||
| //
 | ||||
| //    private OAuth2RequestValidator oAuth2RequestValidator = new DefaultOAuth2RequestValidator();
 | ||||
| //    private WebResponseExceptionTranslator providerExceptionHandler = new DefaultWebResponseExceptionTranslator();
 | ||||
|     private static final String DEFAULT_ERROR_URI = "https://datatracker.ietf.org/doc/html/rfc6749#section-5.2"; | ||||
| 
 | ||||
| 
 | ||||
|     @RequestMapping(value = "/oauth2/rest_token", method = RequestMethod.POST) | ||||
|     private final AuthenticationRestConverter authenticationConverter; | ||||
| 
 | ||||
|     private final HttpMessageConverter<OAuth2AccessTokenResponse> accessTokenHttpResponseConverter = | ||||
|             new OAuth2AccessTokenResponseHttpMessageConverter(); | ||||
|     private final HttpMessageConverter<OAuth2Error> errorHttpResponseConverter = | ||||
|             new OAuth2ErrorHttpMessageConverter(); | ||||
| 
 | ||||
| 
 | ||||
|     private AuthenticationManager authenticationManager; | ||||
| 
 | ||||
|     public OAuthRestController() { | ||||
| 
 | ||||
|         this.authenticationConverter = new DelegatingAuthenticationRestConverter( | ||||
|                 Arrays.asList( | ||||
|                         new OAuth2AuthorizationCodeAuthenticationRestConverter(), | ||||
|                         new OAuth2RefreshTokenAuthenticationRestConverter(), | ||||
|                         new OAuth2ClientCredentialsAuthenticationRestConverter(), | ||||
|                         new OAuth2DeviceCodeAuthenticationRestConverter())); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Replace OAuth2TokenEndpointFilter flow use restful API | ||||
|      * | ||||
|      * @param parameters request params | ||||
|      */ | ||||
|     @PostMapping("/oauth2/rest_token") | ||||
|     @ResponseBody | ||||
|     public OAuth2AccessToken postAccessToken(@RequestBody Map<String, String> parameters) { | ||||
|     public void postAccessToken(@RequestBody Map<String, String> parameters, HttpServletResponse response) throws IOException { | ||||
| 
 | ||||
|         try { | ||||
|             String grantType = parameters.get(OAuth2ParameterNames.GRANT_TYPE); | ||||
|             if (grantType == null) { | ||||
|                 throwError(OAuth2ErrorCodes.INVALID_REQUEST, OAuth2ParameterNames.GRANT_TYPE); | ||||
|             } | ||||
| 
 | ||||
| //        String clientId = getClientId(parameters);
 | ||||
| //        ClientDetails authenticatedClient = clientDetailsService.loadClientByClientId(clientId);
 | ||||
| //
 | ||||
| //        //validate client_secret
 | ||||
| //        String clientSecret = getClientSecret(parameters);
 | ||||
| //        if (clientSecret == null || clientSecret.equals("")) {
 | ||||
| //            throw new InvalidClientException("Bad client credentials");
 | ||||
| //        } else {
 | ||||
| //            if (!this.passwordEncoder.matches(clientSecret, authenticatedClient.getClientSecret())) {
 | ||||
| //                throw new InvalidClientException("Bad client credentials");
 | ||||
| //            }
 | ||||
| //        }
 | ||||
| //
 | ||||
| //        TokenRequest tokenRequest = oAuth2RequestFactory.createTokenRequest(parameters, authenticatedClient);
 | ||||
|             Authentication authorizationGrantAuthentication = this.authenticationConverter.convert(parameters); | ||||
|             if (authorizationGrantAuthentication == null) { | ||||
|                 throwError(OAuth2ErrorCodes.UNSUPPORTED_GRANT_TYPE, OAuth2ParameterNames.GRANT_TYPE); | ||||
|             } | ||||
|             if (authorizationGrantAuthentication instanceof AbstractAuthenticationToken) { | ||||
|                 ((AbstractAuthenticationToken) authorizationGrantAuthentication) | ||||
| //                        .setDetails(this.authenticationDetailsSource.buildDetails(request));
 | ||||
|                         .setDetails(new WebAuthenticationDetails(WebUtils.getIp(), null)); | ||||
|             } | ||||
| 
 | ||||
| //        if (clientId != null && !clientId.equals("")) {
 | ||||
| //            // Only validate the client details if a client authenticated during this
 | ||||
| //            // request.
 | ||||
| //            if (!clientId.equals(tokenRequest.getClientId())) {
 | ||||
| //                // double check to make sure that the client ID in the token request is the same as that in the
 | ||||
| //                // authenticated client
 | ||||
| //                throw new InvalidClientException("Given client ID does not match authenticated client");
 | ||||
| //            }
 | ||||
| //        }
 | ||||
| //
 | ||||
| //        oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient);
 | ||||
| 
 | ||||
| //        final String grantType = tokenRequest.getGrantType();
 | ||||
| //        if (!StringUtils.hasText(grantType)) {
 | ||||
| //            throw new InvalidRequestException("Missing grant type");
 | ||||
| //        }
 | ||||
| //        if (grantType.equals("implicit")) {
 | ||||
| //            throw new InvalidGrantException("Implicit grant type not supported from token endpoint");
 | ||||
| //        }
 | ||||
| //
 | ||||
| //        if (isAuthCodeRequest(parameters)) {
 | ||||
| //            // The scope was requested or determined during the authorization step
 | ||||
| //            if (!tokenRequest.getScope().isEmpty()) {
 | ||||
| //                LOG.debug("Clearing scope of incoming token request");
 | ||||
| //                tokenRequest.setScope(Collections.<String>emptySet());
 | ||||
| //            }
 | ||||
| //        }
 | ||||
| 
 | ||||
| 
 | ||||
| //        if (isRefreshTokenRequest(parameters)) {
 | ||||
| //            // A refresh token has its own default scopes, so we should ignore any added by the factory here.
 | ||||
| //            tokenRequest.setScope(OAuth2Utils.parseParameterList(parameters.get(OAuth2Utils.SCOPE)));
 | ||||
| //        }
 | ||||
| //
 | ||||
| //        OAuth2AccessToken token = getTokenGranter(grantType).grant(grantType, tokenRequest);
 | ||||
| //        if (token == null) {
 | ||||
| //            throw new UnsupportedGrantTypeException("Unsupported grant type: " + grantType);
 | ||||
| //        }
 | ||||
| 
 | ||||
| 
 | ||||
| //        return token;
 | ||||
|         throw new UnsupportedOperationException("Not yet implements"); | ||||
|     } | ||||
| 
 | ||||
| //    protected TokenGranter getTokenGranter(String grantType) {
 | ||||
| //
 | ||||
| //        if ("authorization_code".equals(grantType)) {
 | ||||
| //            return new AuthorizationCodeTokenGranter(tokenServices, authorizationCodeServices, clientDetailsService, this.oAuth2RequestFactory);
 | ||||
| //        } else if ("password".equals(grantType)) {
 | ||||
| //            return new ResourceOwnerPasswordTokenGranter(getAuthenticationManager(), tokenServices, clientDetailsService, this.oAuth2RequestFactory);
 | ||||
| //        } else if ("refresh_token".equals(grantType)) {
 | ||||
| //            return new RefreshTokenGranter(tokenServices, clientDetailsService, this.oAuth2RequestFactory);
 | ||||
| //        } else if ("client_credentials".equals(grantType)) {
 | ||||
| //            return new ClientCredentialsTokenGranter(tokenServices, clientDetailsService, this.oAuth2RequestFactory);
 | ||||
| //        } else if ("implicit".equals(grantType)) {
 | ||||
| //            return new ImplicitTokenGranter(tokenServices, clientDetailsService, this.oAuth2RequestFactory);
 | ||||
| //        } else {
 | ||||
| //            throw new UnsupportedGrantTypeException("Unsupport grant_type: " + grantType);
 | ||||
| //        }
 | ||||
| //    }
 | ||||
| 
 | ||||
| 
 | ||||
| //    @ExceptionHandler(Exception.class)
 | ||||
| //    public ResponseEntity<OAuth2Exception> handleException(Exception e) throws Exception {
 | ||||
| //        LOG.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage());
 | ||||
| //        return getExceptionTranslator().translate(e);
 | ||||
| //    }
 | ||||
| 
 | ||||
| //    @ExceptionHandler(ClientRegistrationException.class)
 | ||||
| //    public ResponseEntity<OAuth2Exception> handleClientRegistrationException(Exception e) throws Exception {
 | ||||
| //        LOG.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage());
 | ||||
| //        return getExceptionTranslator().translate(new BadClientCredentialsException());
 | ||||
| //    }
 | ||||
| //
 | ||||
| //    @ExceptionHandler(OAuth2Exception.class)
 | ||||
| //    public ResponseEntity<OAuth2Exception> handleException(OAuth2Exception e) throws Exception {
 | ||||
| //        LOG.info("Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage());
 | ||||
| //        return getExceptionTranslator().translate(e);
 | ||||
| //    }
 | ||||
| 
 | ||||
| 
 | ||||
| //    private boolean isRefreshTokenRequest(Map<String, String> parameters) {
 | ||||
| //        return "refresh_token".equals(parameters.get(OAuth2Utils.GRANT_TYPE)) && parameters.get("refresh_token") != null;
 | ||||
| //    }
 | ||||
| //
 | ||||
| //    private boolean isAuthCodeRequest(Map<String, String> parameters) {
 | ||||
| //        return "authorization_code".equals(parameters.get(OAuth2Utils.GRANT_TYPE)) && parameters.get("code") != null;
 | ||||
| //    }
 | ||||
| 
 | ||||
| 
 | ||||
| //    protected String getClientId(Map<String, String> parameters) {
 | ||||
| //        return parameters.get(OAuth2Utils.CLIENT_ID);
 | ||||
| //    }
 | ||||
| 
 | ||||
|     protected String getClientSecret(Map<String, String> parameters) { | ||||
|         return parameters.get("client_secret"); | ||||
|             OAuth2AccessTokenAuthenticationToken accessTokenAuthentication = | ||||
|                     (OAuth2AccessTokenAuthenticationToken) this.authenticationManager.authenticate(authorizationGrantAuthentication); | ||||
|             this.sendAccessTokenResponse(response, accessTokenAuthentication); | ||||
|         } catch (OAuth2AuthenticationException ex) { | ||||
|             SecurityContextHolder.clearContext(); | ||||
|             if (LOG.isTraceEnabled()) { | ||||
|                 LOG.trace("Token request failed: {}", ex.getError(), ex); | ||||
|             } | ||||
|             this.sendErrorResponse(response, ex); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| //    private AuthenticationManager getAuthenticationManager() {
 | ||||
| //        return this.authenticationManager;
 | ||||
| //    }
 | ||||
|     private void sendErrorResponse(HttpServletResponse response, | ||||
|                                    AuthenticationException exception) throws IOException { | ||||
| 
 | ||||
|         OAuth2Error error = ((OAuth2AuthenticationException) exception).getError(); | ||||
|         ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response); | ||||
|         httpResponse.setStatusCode(HttpStatus.BAD_REQUEST); | ||||
|         this.errorHttpResponseConverter.write(error, null, httpResponse); | ||||
|     } | ||||
| 
 | ||||
|     private void sendAccessTokenResponse(HttpServletResponse response, Authentication authentication) throws IOException { | ||||
| 
 | ||||
|         OAuth2AccessTokenAuthenticationToken accessTokenAuthentication = | ||||
|                 (OAuth2AccessTokenAuthenticationToken) authentication; | ||||
| 
 | ||||
|         OAuth2AccessToken accessToken = accessTokenAuthentication.getAccessToken(); | ||||
|         OAuth2RefreshToken refreshToken = accessTokenAuthentication.getRefreshToken(); | ||||
|         Map<String, Object> additionalParameters = accessTokenAuthentication.getAdditionalParameters(); | ||||
| 
 | ||||
|         OAuth2AccessTokenResponse.Builder builder = | ||||
|                 OAuth2AccessTokenResponse.withToken(accessToken.getTokenValue()) | ||||
|                         .tokenType(accessToken.getTokenType()) | ||||
|                         .scopes(accessToken.getScopes()); | ||||
|         if (accessToken.getIssuedAt() != null && accessToken.getExpiresAt() != null) { | ||||
|             builder.expiresIn(ChronoUnit.SECONDS.between(accessToken.getIssuedAt(), accessToken.getExpiresAt())); | ||||
|         } | ||||
|         if (refreshToken != null) { | ||||
|             builder.refreshToken(refreshToken.getTokenValue()); | ||||
|         } | ||||
|         if (!CollectionUtils.isEmpty(additionalParameters)) { | ||||
|             builder.additionalParameters(additionalParameters); | ||||
|         } | ||||
|         OAuth2AccessTokenResponse accessTokenResponse = builder.build(); | ||||
|         ServletServerHttpResponse httpResponse = new ServletServerHttpResponse(response); | ||||
|         this.accessTokenHttpResponseConverter.write(accessTokenResponse, null, httpResponse); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     private static void throwError(String errorCode, String parameterName) { | ||||
|         OAuth2Error error = new OAuth2Error(errorCode, "OAuth 2.0 Parameter: " + parameterName, DEFAULT_ERROR_URI); | ||||
|         throw new OAuth2AuthenticationException(error); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public void afterPropertiesSet() throws Exception { | ||||
| 
 | ||||
| //        Assert.state(clientDetailsService != null, "ClientDetailsService must be provided");
 | ||||
| //        Assert.state(authenticationManager != null, "AuthenticationManager must be provided");
 | ||||
| 
 | ||||
|         Assert.notNull(this.passwordEncoder, "PasswordEncoder is null"); | ||||
| 
 | ||||
| //        oAuth2RequestFactory = new DefaultOAuth2RequestFactory(clientDetailsService);
 | ||||
|     } | ||||
| 
 | ||||
| //    protected WebResponseExceptionTranslator getExceptionTranslator() {
 | ||||
| //        return providerExceptionHandler;
 | ||||
| //    }
 | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { | ||||
|  | @ -211,4 +176,5 @@ public class OAuthRestController implements InitializingBean, ApplicationContext | |||
| //            this.authenticationManager = (AuthenticationManager) applicationContext.getBean("authenticationManagerBean");
 | ||||
| //        }
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 shengzhaoli.shengz
						shengzhaoli.shengz