zhou-hao 4 роки тому
батько
коміт
e41dbaba6a

+ 3 - 3
hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/OAuth2Request.java

@@ -13,15 +13,15 @@ import java.util.Optional;
 @AllArgsConstructor
 public class OAuth2Request {
 
-    private Map<String, Object> parameters;
+    private Map<String, String> parameters;
 
 
-    public Optional<Object> getParameter(String key) {
+    public Optional<String> getParameter(String key) {
         return Optional.ofNullable(parameters)
                 .map(params -> params.get(key));
     }
 
-    public OAuth2Request with(String parameter, Object key) {
+    public OAuth2Request with(String parameter, String key) {
         if (parameters == null) {
             parameters = new HashMap<>();
         }

+ 1 - 1
hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/code/AuthorizationCodeRequest.java

@@ -19,7 +19,7 @@ public class AuthorizationCodeRequest extends OAuth2Request {
 
     public AuthorizationCodeRequest(OAuth2Client client,
                                     Authentication authentication,
-                                    Map<String, Object> parameters) {
+                                    Map<String, String> parameters) {
         super(parameters);
         this.client = client;
         this.authentication = authentication;

+ 1 - 1
hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/code/AuthorizationCodeTokenRequest.java

@@ -15,7 +15,7 @@ public class AuthorizationCodeTokenRequest extends OAuth2Request {
 
     private OAuth2Client client;
 
-    public AuthorizationCodeTokenRequest(OAuth2Client client, Map<String, Object> parameters) {
+    public AuthorizationCodeTokenRequest(OAuth2Client client, Map<String, String> parameters) {
         super(parameters);
         this.client = client;
     }

+ 1 - 1
hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/credential/ClientCredentialRequest.java

@@ -11,7 +11,7 @@ public class ClientCredentialRequest extends OAuth2Request {
 
     private final OAuth2Client client;
 
-    public ClientCredentialRequest(OAuth2Client client, Map<String, Object> parameters) {
+    public ClientCredentialRequest(OAuth2Client client, Map<String, String> parameters) {
         super(parameters);
         this.client = client;
     }

+ 48 - 13
hsweb-authorization/hsweb-authorization-oauth2/src/main/java/org/hswebframework/web/oauth2/server/web/OAuth2AuthorizeController.java

@@ -19,7 +19,9 @@ import org.hswebframework.web.oauth2.server.OAuth2GrantService;
 import org.hswebframework.web.oauth2.server.code.AuthorizationCodeRequest;
 import org.hswebframework.web.oauth2.server.code.AuthorizationCodeTokenRequest;
 import org.hswebframework.web.oauth2.server.credential.ClientCredentialRequest;
+import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
+import org.springframework.util.MultiValueMap;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.server.ServerWebExchange;
 import reactor.core.publisher.Mono;
@@ -48,29 +50,30 @@ public class OAuth2AuthorizeController {
             @Parameter(name = "response_type", description = "固定值为code")
     })
     public Mono<String> authorizeByCode(ServerWebExchange exchange) {
-        Map<String, Object> param = new HashMap<>(exchange.getRequest().getQueryParams().toSingleValueMap());
+        Map<String, String> param = new HashMap<>(exchange.getRequest().getQueryParams().toSingleValueMap());
 
         return Authentication
                 .currentReactive()
                 .switchIfEmpty(Mono.error(UnAuthorizedException::new))
                 .flatMap(auth -> this
-                        .getOAuth2Client((String) param.get("client_id"))
-                        .switchIfEmpty(Mono.error(() -> new OAuth2Exception(ErrorType.ILLEGAL_CLIENT_ID)))
+                        .getOAuth2Client(param.get("client_id"))
                         .flatMap(client -> {
-                            String redirectUri = (String) param.getOrDefault("redirect_uri", client.getRedirectUrl());
+                            String redirectUri = param.getOrDefault("redirect_uri", client.getRedirectUrl());
                             client.validateRedirectUri(redirectUri);
                             return oAuth2GrantService
                                     .authorizationCode()
                                     .requestCode(new AuthorizationCodeRequest(client, auth, param))
                                     .doOnNext(response -> {
-                                        Optional.ofNullable(param.get("state")).ifPresent(state -> response.with("state", state));
+                                        Optional
+                                                .ofNullable(param.get("state"))
+                                                .ifPresent(state -> response.with("state", state));
                                     })
                                     .map(response -> buildRedirect(redirectUri, response.getParameters()));
                         }));
     }
 
     @GetMapping(value = "/token")
-    @Operation(summary = "使用申请token", parameters = {
+    @Operation(summary = "(GET)申请token", parameters = {
             @Parameter(name = "client_id"),
             @Parameter(name = "client_secret"),
             @Parameter(name = "code", description = "grantType为authorization_code时不能为空"),
@@ -89,10 +92,33 @@ public class OAuth2AuthorizeController {
                 .map(ResponseEntity::ok);
     }
 
+
+    @PostMapping(value = "/token", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
+    @Operation(summary = "(POST)申请token", parameters = {
+            @Parameter(name = "client_id"),
+            @Parameter(name = "client_secret"),
+            @Parameter(name = "code", description = "grantType为authorization_code时不能为空"),
+            @Parameter(name = "grant_type", schema = @Schema(implementation = GrantType.class))
+    })
+    @Authorize(ignore = true)
+    public Mono<ResponseEntity<AccessToken>> requestTokenByCode(ServerWebExchange exchange) {
+        return exchange
+                .getFormData()
+                .map(MultiValueMap::toSingleValueMap)
+                .flatMap(params -> {
+                    GrantType grantType = GrantType.of(params.get("grant_type"));
+                    return this
+                            .getOAuth2Client(params.get("client_id"))
+                            .doOnNext(client -> client.validateSecret(params.get("client_secret")))
+                            .flatMap(client -> grantType.requestToken(oAuth2GrantService, client, new HashMap<>(params)))
+                            .map(ResponseEntity::ok);
+                });
+    }
+
     public enum GrantType {
         authorization_code {
             @Override
-            Mono<AccessToken> requestToken(OAuth2GrantService service, OAuth2Client client, Map<String, Object> param) {
+            Mono<AccessToken> requestToken(OAuth2GrantService service, OAuth2Client client, Map<String, String> param) {
                 return service
                         .authorizationCode()
                         .requestToken(new AuthorizationCodeTokenRequest(client, param));
@@ -100,14 +126,22 @@ public class OAuth2AuthorizeController {
         },
         client_credentials {
             @Override
-            Mono<AccessToken> requestToken(OAuth2GrantService service, OAuth2Client client, Map<String, Object> param) {
+            Mono<AccessToken> requestToken(OAuth2GrantService service, OAuth2Client client, Map<String, String> param) {
                 return service
                         .clientCredential()
                         .requestToken(new ClientCredentialRequest(client, param));
             }
         };
 
-        abstract Mono<AccessToken> requestToken(OAuth2GrantService service, OAuth2Client client, Map<String, Object> param);
+        abstract Mono<AccessToken> requestToken(OAuth2GrantService service, OAuth2Client client, Map<String, String> param);
+
+        static GrantType of(String name){
+            try {
+                return GrantType.valueOf(name);
+            }catch (Throwable e){
+                throw new OAuth2Exception(ErrorType.UNSUPPORTED_GRANT_TYPE);
+            }
+        }
     }
 
     @SneakyThrows
@@ -117,9 +151,9 @@ public class OAuth2AuthorizeController {
 
     static String buildRedirect(String redirectUri, Map<String, Object> params) {
         String paramsString = params.entrySet()
-                .stream()
-                .map(e -> e.getKey() + "=" + urlEncode(String.valueOf(e.getValue())))
-                .collect(Collectors.joining("&"));
+                                    .stream()
+                                    .map(e -> e.getKey() + "=" + urlEncode(String.valueOf(e.getValue())))
+                                    .collect(Collectors.joining("&"));
         if (redirectUri.contains("?")) {
             return redirectUri + "&" + paramsString;
         }
@@ -128,6 +162,7 @@ public class OAuth2AuthorizeController {
 
     private Mono<OAuth2Client> getOAuth2Client(String id) {
         return clientManager
-                .getClient(id);
+                .getClient(id)
+                .switchIfEmpty(Mono.error(() -> new OAuth2Exception(ErrorType.ILLEGAL_CLIENT_ID)));
     }
 }