【问题标题】:Spring OAuth2 Resource allowed only for clients and token auto creationSpring OAuth2 资源仅允许用于客户端和令牌自动创建
【发布时间】:2015-03-24 12:06:48
【问题描述】:

我有一个应用程序正在使用 OAuth2 password grant type 来管理用户对其资源的授权。所有 App 资源只允许使用一次提供的令牌代表某个用户进行操作的客户端访问,但创建用户的 URI 除外,我希望只有经过身份验证的客户端才能访问它。我正在使用 spring-security-oauth2 作为我的 OAuth 实现,但无法弄清楚如何以一种比下面描述的方式更简单的方式来实现这一点:

POST /users 只能由经过身份验证的客户端访问。

目前我通过删除@EnableAuthorizationServer 并创建一个新类并扩展AuthorizationServerSecurityConfiguration 类和覆盖方法:configure( HttpSecurity http ) 并创建一个新的@Configuration 类和@Import AuthorizationServerEndpointsConfiguration 和@ 987654331@。 问题是,在我的新自定义 class 中,我需要在被覆盖的方法中覆盖并复制/粘贴整个方法的原始代码,以类似以下内容结尾:

@Override protected void configure( HttpSecurity http ) throws Exception { AuthorizationServerSecurityConfigurer configurer = new AuthorizationServerSecurityConfigurer(); FrameworkEndpointHandlerMapping handlerMapping = endpoints.oauth2EndpointHandlerMapping(); http.setSharedObject(FrameworkEndpointHandlerMapping.class, handlerMapping); configure(configurer); http.apply(configurer); String tokenEndpointPath = handlerMapping.getServletPath("/oauth/token"); String tokenKeyPath = handlerMapping.getServletPath("/oauth/token_key"); String checkTokenPath = handlerMapping.getServletPath("/oauth/check_token"); http .authorizeRequests() .antMatchers(tokenEndpointPath).fullyAuthenticated() .antMatchers( HttpMethod.POST, "/users/**").fullyAuthenticated() .antMatchers(tokenKeyPath).access(configurer.getTokenKeyAccess()) .antMatchers(checkTokenPath).access(configurer.getCheckTokenAccess()) .and() .requestMatchers() .requestMatchers( new AntPathRequestMatcher(tokenKeyPath), new AntPathRequestMatcher(tokenEndpointPath), new AntPathRequestMatcher(checkTokenPath), new AntPathRequestMatcher("/users/**", HttpMethod.POST.name())); http.setSharedObject(ClientDetailsService.class, clientDetailsService); } 我的第一个问题是,有更好的方法吗?

我想做的第二件事是在创建新用户时通过密码授予类型自动创建 AccessToken(在 URI POST /users 中),我想不出任何方法来做到这一点。

有人可以提供关于这两个需求的任何见解吗?

谢谢

【问题讨论】:

    标签: java spring spring-mvc oauth spring-security-oauth2


    【解决方案1】:

    不确定这是否是您要问的,但我理解的是您想要的 使用 POST 方法为 /users 端点上的请求配置特定的安全约束。所以 我就是这样做的。我不认为扩展 AuthorizationServerSecurityConfiguration 是必要的,因为推荐的方式 通常只是在你的主目录中扩展WebSecurityConfigurerAdapter 安全配置类,请记住,您可以为多个端点多次配置 HttpSecurity,但如果您在多个位置配置相同的端点,则最后一次读取的配置将是一个活动的

               @EnableWebSecurity public class SecurityConfiguration extends
               WebSecurityConfigurerAdapter {
               //other methods ...
    
               @Override
               @Bean 
               public AuthenticationManager authenticationManagerBean() throws
               Exception { 
                  return super.authenticationManagerBean();
               }
    
               @Order(1)
               @Override 
               protected void configure(HttpSecurity http) throws Exception {  
                    //configure your path here
                    //I purposly configured GET user to
                    // permit all to see diference
                    //for example
                    // @formatter:off
                    http
                    .authorizeRequests()
                    .antMatchers(HttpMethod.GET,"/user")
                    .permitAll() 
                    .antMatchers(HttpMethod.POST,"/user")
                    .fullyAuthenticated()
                    .and().csrf().disable()
                    .formLogin();
                    // @formatter:on
                }
    
           }
    

    然后在你的 Ouath 配置中

    @Configuration
    public class OAuth2ServerConfiguration {
    
        private static final String RESOURCE_ID = "restservice";
    
        @Configuration
        @EnableResourceServer
        protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
    
            @Override
            public void configure(ResourceServerSecurityConfigurer resources) {
                // @formatter:off
                resources
                    .resourceId(RESOURCE_ID);
                // @formatter:on
            }
    
            @Override
            public void configure(HttpSecurity http) throws Exception {
                // @formatter:off
                 http
                    .requestMatchers()
                    .antMatchers("/resources/**","/greeting")
                    .and() 
                    .authorizeRequests()
                    .antMatchers("/resources").access("#oauth2.hasScope('read') or hasRole('ROLE_USER')")
                    .antMatchers("/greeting").access("#oauth2.hasScope('read')"); 
                }
        }
    
        @Configuration
        @EnableAuthorizationServer
        protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
    
            private TokenStore tokenStore = new InMemoryTokenStore();
    
            @Autowired
            @Qualifier("authenticationManagerBean")
            private AuthenticationManager authenticationManager;
    
            @Override
            public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
                // @formatter:off
                endpoints
                    .tokenStore(this.tokenStore)
                    .authenticationManager(authenticationManager);
                    // @formatter:on
            }
    
            @Override
            public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
                // @formatter:off
                clients
                    .inMemory()
                        .withClient("clientapp")
                            .authorizedGrantTypes("password","refresh_token")
                            .authorities("USER")
                            .scopes("read", "write")
                            .resourceIds(RESOURCE_ID)
                            .secret("123456");
                // @formatter:on
    
            }
    
            @Bean
            @Primary
            public DefaultTokenServices tokenServices() {
                DefaultTokenServices tokenServices = new DefaultTokenServices();
                tokenServices.setSupportRefreshToken(true);
                tokenServices.setTokenStore(this.tokenStore);
                return tokenServices;
            }
    
        }
    
    }
    

    正如您在上面看到的,HttpSecurity 在扩展 WebSecurityConfigurerAdapter 的类中配置了两次,并且在扩展ResourceServerConfigurerAdapter 的类中为您的 Ouath 配置配置了两次

    这个例子的一部分来自 royclarkson 的这个 gitHub 例子 https://github.com/royclarkson/spring-rest-service-oauth

    我不确定你在第二个问题中问的是什么,你能澄清一下吗?

    【讨论】:

    • 看看这个帖子:Github,我在那里发布了同样的问题,讨论将澄清我对你的需求。我的第二个问题是我如何通过/users 资源中的password grant type 流为用户创建令牌,换句话说我需要在/users 中生成OAuth2AccessToken,你知道一些简单的策略吗? ?
    • 如果您发布了您的 configure ClientDetailsServiceConfigurer 配置,可能会更容易,我查看了您的 git hub,但我仍然不明白您为什么要这样配置,dsyer 给了您几乎相同的解决方案正如我在上面给你的,创建具有自己的安全约束的不同端点/用户,并在该端点内部获取令牌并以 JSON 格式将其返回给用户,如果这是你想要返回的内容
    • 在上面的帖子中,我添加了DefaultTokenServices,如果您提供OAuth2Authentication 对象,您可以从中获取令牌,不确定这是否适合将这些东西与控制器混合,但它是一个 Bean,您可以自动装配它
    • user1289300 正如你在我上次在 Github 上的评论中看到的那样,我放弃了我的自定义配置,我将使用 client_credentials 授权类型来完成对 /users 资源的定义和保护,仅用于客户。关于你对DefaultTokenService的建议,我会试一试,谢谢!
    • 我设法从DefaultTokenServices 生成令牌,感谢您的帮助,我不会将您的答案标记为正确,因为在我的情况下,最好的解决方案是使用client_credentials 流来保护/users资源,好吗!?我将分享我的解决方案以使事情更清楚。再次感谢。
    猜你喜欢
    • 2015-05-25
    • 2019-04-24
    • 2015-06-02
    • 1970-01-01
    • 1970-01-01
    • 2019-03-03
    • 2015-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多