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

查看:162
本文介绍了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

使用客户端 ID 和密码以及授权类型和代码,使用基本身份验证构建 GET 请求:http://localhost:8080/server/oauth/token?grant_type=authorization_code&code=HMJO4K

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" }

再次POST到令牌uri以刷新令牌:http://localhost:8080/server/oauth/token?grant_type=refresh_token&refresh_token=57100377-dea9-4df0-adab-62e33f2a1b49

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天全站免登陆