尝试使用spring oauth2中的刷新令牌获取新的访问令牌时出现无效的客户端错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尝试使用spring oauth2中的刷新令牌获取新的访问令牌时出现无效的客户端错误相关的知识,希望对你有一定的参考价值。

当我点击url获取访问令牌以及刷新令牌时它工作正常。

url:- http://localhost:8080/thela-web/oauth/token?grant_type=password&client_id=thelaapp&client_secret=thelaapp&username=8527886649&password=Pkc12345@

回应是完美的

{
    "access_token": "6ae54dc4-3dbf-48e6-9b7a-d58ececd48df",
    "token_type": "bearer",
    "refresh_token": "7c752534-0945-464d-b6d3-2027205630f3",
    "expires_in": 1799,
    "scope": "read write trust"
}

但我试图在春天使用刷新令牌获取访问令牌,它给出了一个错误。

url:-http://localhost:8080/thela-web/oauth/token?grant_type=refresh_token&refresh_token=7c752534-0945-464d-b6d3-2027205630f3

我得到了回应

{
    "error": "invalid_client",
    "error_description": "Bad client credentials"
}

授权服务器配置类。

package com.endowment.thela.oauth2.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.token.TokenStore;

import com.endowment.thela.webapp.constatnt.SecurityConstatnt;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter{


    private static final String GRANT_TYPE_PASSWORD="password";
    private static final String GRANT_TYPE_AUTHORIZATION_CODE="authorization_code";
    private static final String GRANT_TYPE_REFRESH_TOKEN="refresh_token";
    private static final String GRANT_TYPE_IMPLICIT="implicit";
    private static final String AUTHORITY_ROLE_CLIENT="ROLE_CLIENT";
    private static final String AUTHORITY_ROLE_TRUSTED_CLIENT="ROLE_TRUSTED_CLIENT";
    private static final String SCOPE_READ="read";
    private static final String SCOPE_WRITE="write";
    private static final String SCOPE_TRUST="trust";

    @Value("${oauth2.client_id}")
    private String clientId;

    @Value("${oauth2.client_secret}")
    private String clientSecret;

    @Value("${oauth2.access_token.validity_second}")
    private int accessTokenValiditySeconds;

    @Value("${oauth2.refresh_token.validity_second}")
    private int refreshTokenValiditySeconds;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private UserApprovalHandler userApprovalHandler;

    @Autowired
    @Qualifier("authenticationManagerBean")
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory().withClient(clientId)
            .authorizedGrantTypes(GRANT_TYPE_PASSWORD, GRANT_TYPE_AUTHORIZATION_CODE, GRANT_TYPE_REFRESH_TOKEN, GRANT_TYPE_IMPLICIT)
            .authorities(AUTHORITY_ROLE_CLIENT, AUTHORITY_ROLE_TRUSTED_CLIENT)
            .scopes(SCOPE_READ, SCOPE_WRITE, SCOPE_TRUST)
            .secret(clientSecret)
            .accessTokenValiditySeconds(accessTokenValiditySeconds).
            refreshTokenValiditySeconds(refreshTokenValiditySeconds);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
                .authenticationManager(authenticationManager);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.realm(SecurityConstatnt.REALM).allowFormAuthenticationForClients();
    }

}

日志:

2018-03-02 22:51:47 DEBUG OrRequestMatcher:65 - Trying to match using Ant [pattern='/oauth/token']
2018-03-02 22:51:47 DEBUG AntPathRequestMatcher:151 - Checking match of request : '/oauth/token'; against '/oauth/token'
2018-03-02 22:51:47 DEBUG OrRequestMatcher:68 - matched
2018-03-02 22:51:47 DEBUG FilterChainProxy:324 - /oauth/token?grant_type=refresh_token&client_id=thelaaap&client_secret=thelaaap&refresh_token=7a7916a3-4087-42fe-8b7e-7addaacf7bee at position 1 of 12 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2018-03-02 22:51:47 DEBUG FilterChainProxy:324 - /oauth/token?grant_type=refresh_token&client_id=thelaaap&client_secret=thelaaap&refresh_token=7a7916a3-4087-42fe-8b7e-7addaacf7bee at position 2 of 12 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2018-03-02 22:51:47 DEBUG FilterChainProxy:324 - /oauth/token?grant_type=refresh_token&client_id=thelaaap&client_secret=thelaaap&refresh_token=7a7916a3-4087-42fe-8b7e-7addaacf7bee at position 3 of 12 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2018-03-02 22:51:47 DEBUG HstsHeaderWriter:128 - Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@1690ba43
2018-03-02 22:51:47 DEBUG FilterChainProxy:324 - /oauth/token?grant_type=refresh_token&client_id=thelaaap&client_secret=thelaaap&refresh_token=7a7916a3-4087-42fe-8b7e-7addaacf7bee at position 4 of 12 in additional filter chain; firing Filter: 'LogoutFilter'
2018-03-02 22:51:47 DEBUG AntPathRequestMatcher:151 - Checking match of request : '/oauth/token'; against '/logout'
2018-03-02 22:51:47 DEBUG FilterChainProxy:324 - /oauth/token?grant_type=refresh_token&client_id=thelaaap&client_secret=thelaaap&refresh_token=7a7916a3-4087-42fe-8b7e-7addaacf7bee at position 5 of 12 in additional filter chain; firing Filter: 'ClientCredentialsTokenEndpointFilter'
2018-03-02 22:51:47 DEBUG ClientCredentialsTokenEndpointFilter:211 - Request is to process authentication
2018-03-02 22:51:47 DEBUG ProviderManager:162 - Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2018-03-02 22:51:47 DEBUG DefaultListableBeanFactory:251 - Returning cached instance of singleton bean 'scopedTarget.clientDetailsService'
2018-03-02 22:51:47 DEBUG DaoAuthenticationProvider:147 - User 'thelaaap' not found
2018-03-02 22:51:47 DEBUG ClientCredentialsTokenEndpointFilter:350 - Authentication request failed: org.springframework.security.authentication.BadCredentialsException: Bad credentials
2018-03-02 22:51:47 DEBUG ClientCredentialsTokenEndpointFilter:351 - Updated SecurityContextHolder to contain null Authentication
2018-03-02 22:51:47 DEBUG ClientCredentialsTokenEndpointFilter:352 - Delegating to authentication failure handler org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter$1@660768ca
2018-03-02 22:51:47 DEBUG DefaultOAuth2ExceptionRenderer:101 - Written [error="invalid_client", error_description="Bad client credentials"] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@6e9cd080]
2018-03-02 22:51:47 DEBUG SecurityContextPersistenceFilter:105 - SecurityContextHolder now cleared, as request processing completed

那么我该如何解决这个问题,请提供解决方案。

答案

您的客户端应将refresh_token注册为grantType

您是否也通过clientid和secret作为base64编码的授权标头?

curl -v -X POST 

   -H "Content-Type: application/json" 

   -H "Authorization: Basic MzUzYjMwMmM0NDU3NGY1NjUwNDU2ODdlNTM0ZTdkNmE6Mjg2OTI0Njk3ZTYxNWE2NzJhNjQ2YTQ5MzU0NTY0NmM=" 

   'http://localhost:8080/test/oauth/token?grant_type=refresh_token&refresh_token=xxxxxx'

更新:

答案似乎与这一行有关

2018-03-02 22:51:47 DEBUG DaoAuthenticationProvider:147 - User 'thelaaap' not found

可能是用户被删除,因此应用程序无法授予refresh_token

以上是关于尝试使用spring oauth2中的刷新令牌获取新的访问令牌时出现无效的客户端错误的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spring Security 5 和 OAuth2 Client 获取刷新令牌并进行 API 调用?

spring security oauth2 (2.0.8) 使用 InMemory tokenstore 获取无效访问令牌

Spring oauth2刷新令牌 - 无法将访问令牌转换为JSON

如何在spring security oauth2中分离访问令牌和刷新令牌端点

Spring oauth2 刷新令牌 - 无法将访问令牌转换为 JSON

使用 spring security 的 oauth2 刷新令牌调用失败,错误:需要 UserDetailsS​​ervice