Java spring OAuth2客户端(资源服务器)总是返回'invalid token'错误

Posted

技术标签:

【中文标题】Java spring OAuth2客户端(资源服务器)总是返回\'invalid token\'错误【英文标题】:Java spring OAuth2 client (resource server) always returns 'invalid token' errorJava spring OAuth2客户端(资源服务器)总是返回'invalid token'错误 【发布时间】:2019-02-14 15:47:12 【问题描述】:

我已经编写了我的烤箱 OAuth2 服务器,我可以成功地从我的服务器检索访问令牌,但是当涉及到客户端时,它总是返回“无效令牌错误”。

我已经搜索并阅读了许多文章、页面和链接,例如以下链接: Spring Security OAuth2 Resource Server Always Returning Invalid Token

但我无法解决问题,这是我的代码,如果你能帮助我,我将不胜感激。

身份验证服务器中的配置:

@Configuration
public class OAuth2Config extends AuthorizationServerConfigurerAdapter 

    private static final String SERVER_RESOURCE_ID = "oauth2-server";

    private static InMemoryTokenStore tokenStore = new InMemoryTokenStore();


    @Configuration
    @EnableResourceServer
    protected static class ResourceServer extends ResourceServerConfigurerAdapter 

        @Override
        public void configure( ResourceServerSecurityConfigurer resources ) throws Exception
            resources.tokenStore( tokenStore ).resourceId( SERVER_RESOURCE_ID );
        

        @Override
        public void configure( HttpSecurity http ) throws Exception 
            http.requestMatchers().antMatchers("/user").and().authorizeRequests().antMatchers("/me").access("#oauth2.hasScope('read')");
        

     // ResourceServer


    @Configuration
    @EnableAuthorizationServer
    protected static class AuthConfig extends AuthorizationServerConfigurerAdapter 


        @Autowired
        private AuthenticationManager authenticationManager;


        @Override
        public void configure( ClientDetailsServiceConfigurer  clients ) throws Exception 
            clients.inMemory()
                    .withClient( "insert_server" ) // name of client
                    .secret( "noop" + "123456" )
                    .authorizedGrantTypes( "refresh_token", "password", "client_credentials" )
                    .scopes( "webclient", "mobileclient" )
                    .resourceIds( SERVER_RESOURCE_ID )
                    .and().withClient("rest_server")
                    .secret( "noop" + "123456" )
                    .authorizedGrantTypes( "refresh_token", "password", "client_credentials" )
                    .scopes( "webclient", "mobileclient" )
                    .resourceIds( SERVER_RESOURCE_ID );


            //System.out.println( encoder.encode("123456") );
        


        @Override
        public void configure( AuthorizationServerEndpointsConfigurer endPoints ) throws Exception  
           /* endPoints
                    .authenticationManager( this.authenticationManager )
                    .userDetailsService( this.userDetailsService ); */

           endPoints.authenticationManager( this.authenticationManager )
                   .tokenStore( tokenStore )
                   .approvalStoreDisabled();
        

     // AuthConfig


身份验证服务器中的 Web 安全类:

@Configuration
public class WebSecutiryConfigurer extends WebSecurityConfigurerAdapter 

    private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();


    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean( ) throws Exception 
        return super.authenticationManagerBean();
    


    @Override
    @Bean
    public UserDetailsService userDetailsServiceBean( ) throws Exception 
        return super.userDetailsServiceBean();
    


    @Override
    protected void configure( AuthenticationManagerBuilder auth ) throws Exception
        auth.inMemoryAuthentication()
                .withUser( "pswin ")
                    .password( "noop" + "123456" )
                    .roles( "USER" )
                .and().withUser( "admin" ) // username
                    .password( "noop" + "123456" ) // password
                    .roles( "USER", "ADMIN" ); // roles
    

客户端配置:

security.oauth2.client.client-id=rest_server
security.oauth2.client.client-secret=123456
security.oauth2.client.access-token-uri=http://localhost:8989/auth/oauth/token
security.oauth2.client.user-authorization-uri=http://localhost:8989/auth/oauth/authorize
security.oauth2.resource.user-info-uri=http://localhost:8989/auth/user

和我的控制器:

@RestController
@RequestMapping( "/city" )
@EnableResourceServer
public class CityController 

    private CityService cityService;


    //! Constructor
    CityController( CityService cityService )
        this.cityService = cityService;
    



    @GetMapping( "/city_id" )
    public CityDTO getCityByID( @PathVariable Long city_id )
        return new CityDTO( cityService.getByID( city_id ) );
    


    @PreAuthorize("#oauth2.hasScope('webclient')")
    @GetMapping ( "/" )
    public PageDTO getAll( Pageable pageable )
        Page page = this.cityService.getAll( pageable );
        return new PageDTO( page.map( ( city ) -> new CityDTO( (City)city )  ) );
    

更多详情:

Java 版本:10 春季启动版本:2.0.4.RELEASE Spring-cloud 版本:Finchley.SR1

【问题讨论】:

【参考方案1】:

正如您发布的那样,无效的访问令牌通常发生在 1) 客户端发送的令牌与 oauth2 提供程序发出的令牌不同或 2) 如果令牌的 TTL 太短,则可能会过期。如果没有特定的错误消息很难知道,而只是“无效令牌”......但您应该能够在服务器日志中找到更多调试日志(在 spring 端)。

您可以做的一件事是,在 OAuth2AuthenticationProcessingFilter#doFilter() 中添加断点,因为这是 oauth2 检查发生的地方。一步一步调试应该足以让你弄清楚你的令牌出了什么问题。

【讨论】:

以上是关于Java spring OAuth2客户端(资源服务器)总是返回'invalid token'错误的主要内容,如果未能解决你的问题,请参考以下文章

客户端和资源服务器的 Spring OAuth2 XML 配置 [关闭]

Spring OAuth2 客户端,CSRF 保护

使用Spring Security登录认证,通过Oauth2.0开发第三方授授权访问资源项目详解

Spring安全中的Oauth2客户端

OAuth2.0流程

Spring Boot 2 OIDC(OAuth2)客户端/资源服务器未在 WebClient 中传播访问令牌