【问题标题】:Spring Security OAuth2 check_token endpointSpring Security OAuth2 check_token 端点
【发布时间】:2015-01-01 06:41:43
【问题描述】:

我正在尝试使用 spring security oauth 设置资源服务器以与单独的授权服务器一起使用。我正在使用RemoteTokenServices,它需要/check_token 端点。

我可以看到/oauth/check_token 端点在使用@EnableAuthorizationServer 时默认启用。但是,默认情况下无法访问端点。

是否应手动添加以下条目以将此端点列入白名单?

http.authorizeRequests().antMatchers("/oauth/check_token").permitAll();

这将使所有人都可以访问此端点,这是期望的行为吗?或者我错过了什么。

提前致谢,

【问题讨论】:

    标签: spring spring-security oauth-2.0 spring-security-oauth2


    【解决方案1】:

    你必须

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception
    {
       oauthServer.checkTokenAccess("permitAll()");    
    }
    

    有关此的更多信息::

    How to use RemoteTokenService?

    【讨论】:

    • “isAuthenticated()”会不会比“permitAll()”更好?
    • 我写这个是因为他试图在上面的代码中实现这一点。
    • @DaveSyer 据我了解 checkTokenAccess("isAuthenticated()") 将为经过身份验证的用户打开端点。那还需要什么重新定义 http.authorizeRequests().antMatchers("/oauth/check_token").permitAll();
    • 没有必要,据我所知(假设我理解这个问题)。
    【解决方案2】:

    首先,配置令牌访问表达式:

    @Override
    public void configure(AuthorizationServerSecurityConfigurer securityConfigurer) throws Exception {
        securityConfigurer
                .allowFormAuthenticationForClients()
                .checkTokenAccess("isAuthenticated()")
                .addTokenEndpointAuthenticationFilter(checkTokenEndpointFilter());
    }
    

    然后,我们需要定义一个过滤器来处理客户端身份验证:

    @Bean
    public ClientCredentialsTokenEndpointFilter checkTokenEndpointFilter() {
        ClientCredentialsTokenEndpointFilter filter = new ClientCredentialsTokenEndpointFilter("/oauth/check_token");
        filter.setAuthenticationManager(authenticationManager);
        filter.setAllowOnlyPost(true);
        return filter;
    }
    

    【讨论】:

    • 我按照上面的代码,“authenticationManager”是来自WebSecurityConfigurerAdapter.authenticationManagerBean()的@autowird,但是过滤器用于oauth/token org.springframework.security.oauth2.config.annotation。 web.configurers.AuthorizationServerSecurityConfigurer#clientCredentialsTokenEndpointFilter 是 http.getSharedObject(AuthenticationManager.class) 。这两个 authenticationManager 不是同一个。所以当我将数据发布到“/oauth/check_token”时,会出现类似 {“error”:“invalid_client”,“error_description”:“Bad client credentials”} 的错误,不知道为什么它们不一样
    【解决方案3】:

    只是为了澄清几点,并为 Pratik Shah(以及相关主题中的Alex)提供的答案添加更多信息:

    1- 提到的configure 方法通过创建一个扩展AuthorizationServerConfigurerAdapter 的类被覆盖:

        @EnableAuthorizationServer
        @Configuration
        public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
    
            @Override
            public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
                oauthServer.tokenKeyAccess("permitAll()")
                    .checkTokenAccess("isAuthenticated()");
            }
    
            @Override
            public void configure(ClientDetailsServiceConfigurer clients) throws     Exception {
                clients
                        .inMemory()
                        .withClient("ger-client-id")
                        .secret("ger-secret")
                        .authorizedGrantTypes("password")
                        .scopes("read", "write");
            }
        }
    

    2- 我建议阅读this Spring guide 解释当我们包含@EnableAuthorizationServer 注释时Spring Boot 执行的自动配置,包括AuthorizationServerConfigurer bean。如果您像我在上面所做的那样创建扩展 AuthorizationServerConfigurerAdapter 的配置 bean,那么整个自动配置将被禁用。

    3- 如果自动配置非常适合您,并且您只想操作对 /oauth/check_token 端点的访问,您仍然可以在不创建 AuthorizationServerConfigurer bean 的情况下这样做(因此无需以编程方式配置所有内容)。

    您必须将security.oauth2.authorization.check-token-access 属性添加到application.properties 文件中,例如:

    security.oauth2.client.client-id=ger-client-id
    security.oauth2.client.client-secret=ger-secret
    security.oauth2.client.scope=read,write
    
    security.oauth2.authorization.check-token-access=permitAll()
    

    当然,如果你愿意,你可以给它一个isAuthenticated() 值。

    您可以将日志级别设置为 DEBUG 以检查一切是否按预期进行配置:

    16:16:42.763 [main] DEBUG o.s.s.w.a.e.ExpressionBasedFilterInvocationSecurityMetadataSource - Adding web access control expression 'permitAll()', for Ant [pattern='/oauth/check_token']
    

    没有太多关于这些属性的文档,但您可以从this autoconfiguration class 中找出它们。

    最后值得一提的是,尽管它似乎在最新的 Spring 版本中已修复,但我只是在 spring-security-oauth 项目中提交了 an issue;如果您在请求中添加斜杠,则默认情况下会启用 token_check 功能:

    $ curl localhost:8080/oauth/check_token/?token=fc9e4ad4-d6e8-4f57-b67e-c0285dcdeb58
    {"scope":["read","write"],"active":true,"exp":1544940147,"authorities":["ROLE_USER"],"client_id":"ger-client-id"}
    

    【讨论】:

      【解决方案4】:

      POST参数有3个,分别是client_id(用户名)、client_secret(用户名对应的密码)、token(申请的令牌)、client_id、client_secret与/oauth/token接口中的参数不同

      enter image description here

      【讨论】:

        猜你喜欢
        • 2016-02-23
        • 1970-01-01
        • 2015-04-22
        • 2018-09-07
        • 2018-05-26
        • 2017-08-05
        • 2019-02-21
        • 2012-10-22
        • 2019-04-06
        相关资源
        最近更新 更多