【问题标题】:Spring Oauth2 - Customizing TokenEndpoint from @RequestParam to @RequestBodySpring Oauth2 - 自定义从 @RequestParam 到 @RequestBody 的 TokenEndpoint
【发布时间】:2018-06-11 15:07:00
【问题描述】:

我用的是Spring-Security的标准配置,这是我的pom.xml:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath></relativePath>
    </parent>

<dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
        </dependency>
</dependencies>

我必须更改标准令牌请求:

原始令牌请求:

@RequestMapping(value = "/oauth/token", method=RequestMethod.GET)
public ResponseEntity<OAuth2AccessToken> getAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException

想要的令牌请求

@RequestMapping(value = "/oauth/login", method=RequestMethod.POST)
public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestBody UserLogin userLogin) throws HttpRequestMethodNotSupportedException

有可能吗?

我像这样扩展 TokenEndpoint 但不起作用:

public class CustomTokenEndpoint extends TokenEndpoint {

@RequestMapping(value = "/oauth/login", method=RequestMethod.POST)
public ResponseEntity<OAuth2AccessToken> postAccessToken(Principal principal, @RequestBody UserLogin userLogin) throws HttpRequestMethodNotSupportedException {
        return postAccessToken(principal, userLogin.getParameters());
    }
}

【问题讨论】:

    标签: spring-boot spring-security spring-security-oauth2


    【解决方案1】:

    它不会像这样工作,因为您的自定义端点类不会加载到 Spring 过滤器链中。无需扩展TokenEndpoint。您可以创建一个新端点并使其执行原始端点 /oauth/token 所做的事情。

    下面的代码应该可以让您抢占先机。请参阅此代码以了解您的新端点需要做什么。这类似于TokenEndpoint#postAccessToken(...)

    @RequestMapping(value = "/oauth/login", method = RequestMethod.POST)
        public ResponseEntity<OAuth2AccessToken> postAccessToken(final Principal principal, @RequestBody final UserLogin userLogin) throws HttpRequestMethodNotSupportedException {
            if (!(principal instanceof Authentication)) {
                throw new InsufficientAuthenticationException("Client authentication information is missing.");
            }
    
            final Authentication client = (Authentication) principal;
            if (!client.isAuthenticated()) {
                throw new InsufficientAuthenticationException("The client is not authenticated.");
            }
            String clientId = client.getName();
            if (client instanceof OAuth2Authentication) {
                // Might be a client and user combined authentication
                clientId = ((OAuth2Authentication) client).getOAuth2Request().getClientId();
            }
    
            final ClientDetails authenticatedClient = clientDetailsService.loadClientByClientId(clientId);
            final TokenRequest tokenRequest = oAuth2RequestFactory.createTokenRequest(parameters, authenticatedClient);
    
            final Map<String, String> parameters = new HashMap<>();
            parameters.put("username", userLogin.getUsername());
            parameters.put("password", userLogin.getPassword());
            parameters.put("grant_type", userLogin.getGrantType());
            parameters.put("refresh_token", userLogin.getRefreshToken());
            parameters.put("scope", userLogin.getScope());
    
            if (StringUtils.isNotBlank(clientId)) {
                // 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(String.format("Given client ID [%s] does not match the authenticated client", clientId));
                }
            }
    
            if (authenticatedClient != null) {
                oAuth2RequestValidator.validateScope(tokenRequest, authenticatedClient);
            }
            if (!hasText(tokenRequest.getGrantType())) {
                throw new InvalidRequestException("Missing grant type");
            }
    
            final OAuth2AccessToken token;
    
            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)));
                token = refreshTokenGranter.grant(tokenRequest.getGrantType().toLowerCase(), tokenRequest);
            } else {
                token = tokenGranter.grant(tokenRequest.getGrantType().toLowerCase(), tokenRequest);
            }
    
            if (Objects.isNull(token)) {
                throw new UnsupportedGrantTypeException("Unsupported grant type: " + tokenRequest.getGrantType());
            }
    
            return new ResponseEntity<>(token, HttpStatus.OK);
        }
    

    【讨论】:

    猜你喜欢
    • 2016-11-12
    • 2015-11-18
    • 2019-10-14
    • 2011-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 2015-12-30
    相关资源
    最近更新 更多