Spring Security OAuth2资源服务器始终返回无效令牌 [英] Spring Security OAuth2 Resource Server Always Returning Invalid Token

查看:1036
本文介绍了Spring Security OAuth2资源服务器始终返回无效令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Spring库来运行基本的内存OAuth2服务器.我一直在关注 sparklr示例

I am trying to get a basic in-memory OAuth2 server running using the Spring Libraries. I have been following the sparklr example.

我目前已经配置了服务器,并且几乎所有东西都在工作,但是我无法从资源服务器访问受限制的资源.

I currently have configured the Server and almost everything is working, however I cannot access my restricted resource from the resource server.

我的测试工作流程:

  1. 访问oauth授权的URI以启动OAuth2流: http://localhost:8080/server/oauth/authorize?response_type = code& client_id = client

重定向到登录页面: http://localhost:8080/server/login

处理批准并使用代码参数重定向到我配置的重定向页面: http://localhost:8080/client?code = HMJO4K

Handle the approval and redirect to my configured redirect page w/ a code parameter: http://localhost:8080/client?code=HMJO4K

使用客户端身份和密码以及授予类型和代码,使用Basic Auth构造GET请求:

Construct a GET request using Basic Auth using the client id and secret along with the grant type and code: http://localhost:8080/server/oauth/token?grant_type=authorization_code&code=HMJO4K

接收一个access_token并刷新令牌对象作为回报

Receive an access_token and refresh token object in return

{ access_token:"f853bcc5-7801-42d3-9cb8-303fc67b0453" token_type:轴承" refresh_token:"57100377-dea9-4df0-adab-62e33f2a1b49" expires_in:299 范围:读写" }

{ access_token: "f853bcc5-7801-42d3-9cb8-303fc67b0453" token_type: "bearer" refresh_token: "57100377-dea9-4df0-adab-62e33f2a1b49" expires_in: 299 scope: "read write" }

尝试使用access_token访问受限制的资源: http://localhost:8080/server/me?access_token = f853bcc5-7801-42d3-9cb8-303fc67b0453

Attempt to access a restricted resource using the access_token: http://localhost:8080/server/me?access_token=f853bcc5-7801-42d3-9cb8-303fc67b0453

收到无效的令牌回复

{ 错误:"invalid_token" error_description:无效的访问令牌:f853bcc5-7801-42d3-9cb8-303fc67b0453" }

{ error: "invalid_token" error_description: "Invalid access token: f853bcc5-7801-42d3-9cb8-303fc67b0453" }

再次发布到令牌uri以刷新令牌:

POST to the token uri again to refresh token: http://localhost:8080/server/oauth/token?grant_type=refresh_token&refresh_token=57100377-dea9-4df0-adab-62e33f2a1b49

接收新令牌

{ access_token:"ed104994-899c-4cd9-8860-43d5689a9420" token_type:轴承" refresh_token:"57100377-dea9-4df0-adab-62e33f2a1b49" expires_in:300 范围:读写" }

{ access_token: "ed104994-899c-4cd9-8860-43d5689a9420" token_type: "bearer" refresh_token: "57100377-dea9-4df0-adab-62e33f2a1b49" expires_in: 300 scope: "read write" }

我真的不确定自己在做什么错,但是看来除了访问受限制的uri之外的所有其他东西都在起作用.这是我的配置:

I am really not sure what I am doing wrong, but it appears that everything other than accessing the restricted uri is working. Here is my configuration:

@Configuration
public class Oauth2ServerConfiguration {

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

    @Configuration
    @EnableResourceServer
    protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

        @Override
        public void configure(ResourceServerSecurityConfigurer resources) {
            resources.resourceId(SERVER_RESOURCE_ID);
        }

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .and().requestMatchers()
                    .antMatchers("/me")
                .and().authorizeRequests()
                    .antMatchers("/me").access("#oauth2.clientHasRole('ROLE_CLIENT')")
            ;
        }
    }

    @Configuration
    @EnableAuthorizationServer
    protected static class AuthotizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

        @Autowired
        private ClientDetailsService clientDetailsService;

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

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory()
                .withClient("client")
                    .resourceIds(SERVER_RESOURCE_ID)
                    .secret("secret")
                    .authorizedGrantTypes("authorization_code", "refresh_token")
                    .authorities("ROLE_CLIENT")
                    .scopes("read","write")
                    .redirectUris("http://localhost:8080/client")
                    .accessTokenValiditySeconds(300)
                    .autoApprove(true)
            ;
        }

        @Bean
        public TokenStore tokenStore() {
            return new InMemoryTokenStore();
        }

        @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("oauth");
        }

        @Bean
        public ApprovalStore approvalStore() throws Exception {
            TokenApprovalStore store = new TokenApprovalStore();
            store.setTokenStore(tokenStore());
            return store;
        }

        @Bean
        public UserApprovalHandler userApprovalHandler() throws Exception {
            TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
            handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
            handler.setClientDetailsService(clientDetailsService);
            handler.setTokenStore(tokenStore());

            return handler;
        }
    }
}

我是否缺少某些东西,或者我使用的方法不正确?任何帮助将不胜感激.

Is there something I am missing or am I approaching this incorrectly? Any help would be greatly appreciated.

推荐答案

问题最终是资源服务器和授权服务器没有获得相同的令牌存储引用.不确定接线方式如何不正确,但是在配置类中使用固定对象的工作方式很吸引人.最终,我将转到持久性支持的令牌存储,该存储可能不会有任何问题.

The problem ended up being that the resource server and the authorization server were not getting the same token store reference. Not sure how the wiring was not working correctly, but using a fixed object in the configuration class worked like a charm. Ultimately, I'll move to a persistence backed token store, which probably would not have had any issues.

感谢@OhadR提供答案和帮助!

Thanks goes to @OhadR for the answer and the help!

最终,我简化了配置,经历了相同的工作流程,并且解决了

Ultimately, I simplified the configuration, went thru the same workflow, and it worked out

@Configuration
public class Oauth2ServerConfiguration {

    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("/me").and().authorizeRequests().antMatchers("/me").access("#oauth2.hasScope('read')");
        }
    }

    @Configuration
    @EnableAuthorizationServer
    protected static class AuthConfig extends AuthorizationServerConfigurerAdapter {

        @Autowired
        private AuthenticationManager authenticationManager;


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

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
            clients.inMemory()
                .withClient("client")
                    .authorizedGrantTypes("authorization_code","refresh_token")
                    .authorities("ROLE_CLIENT")
                    .scopes("read")
                    .resourceIds(SERVER_RESOURCE_ID)
                    .secret("secret")
            ;
        }
    }
}

偶然发现这篇文章的任何人,我建议您多看一下单元测试,而不要看完整的sparklr/tonr示例,因为它有很多额外的配置,因此不一定要开始使用.

Anyone that stumbles upon this post, I recommend looking more at the unit tests for example rather than the full blown sparklr/tonr example, as it has a lot of extra configuration that are not necessarily needed to get started.

这篇关于Spring Security OAuth2资源服务器始终返回无效令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆