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

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

目前,我通过删除@EnableAuthorizationServer并创建一个新类并扩展AuthorizationServerSecurityConfiguration类并覆盖方法:configure( HttpSecurity http )并创建一个新的@Configuration类以及@Import AuthorizationServerEndpointsConfigurationCustomAuthorizationServerSecurityConfiguration来解决这个问题。
问题是,在我的新自定义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); }
我的第一个问题是,执行此操作的更好方法?

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

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

谢谢

最佳答案

不确定这是否是您要的内容,但我不太了解您是否想要
   使用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的类中两次配置了一次,在您的Ouath配置的扩展类ResourceServerConfigurerAdapter中也进行了两次配置

本示例的一部分摘自royclarkson的gitHub示例
https://github.com/royclarkson/spring-rest-service-oauth

我不确定您在第二个问题中要问的问题,您能澄清一下吗?

09-27 00:21