Spring OAuth2,用userInfoUri访问ROLE?

时间:2015-09-22 12:49:45

标签: spring-security spring-boot spring-security-oauth2

我正在建立单独的资源服务器和授权服务器。现在,我使用资源服务器中的user-info-uri从与访问令牌匹配的授权服务器中提取Principal,并使用config:

spring:
  oauth2:
    resource:
      userInfoUri: http://localhost:9999/uaa/user

在资源服务器中,我根据角色保护端点,如下所示:

http
    .authorizeRequests()
        .antMatchers("/invoices/**").hasRole("END_USER")            
        .anyRequest().authenticated();  

当我手动访问user-info-uri时,我可以看到权限包含:

"authority": "ROLE_END_USER"

但是当我尝试访问/ invoices资源时,我得到一个Access-Denied异常,并在日志中看到:

OAuth2Authentication@bc5074a8: Principal: my-login; Credentials: [PROTECTED]; Authenticated: true; Details: remoteAddress=0:0:0:0:0:0:0:1, tokenType=BearertokenValue=<TOKEN>; Granted Authorities: ROLE_USER

Authoriteis =&#34; ROLE_USER&#34;。它来自何处,应该是&#34; ROLE_END_USER&#34;在这一点上呢?

我已经看到使用共享数据库来存储令牌的实现,这对于我想要实现的内容真的是必要的吗?

资源服务器:

@SpringBootApplication
@EnableOAuth2Resource
public class EndUserResourceServiceApplication extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()                
                .antMatchers("/invoices/**").hasRole("END_USER")                
                .anyRequest().authenticated();  
    }

    public static void main(String[] args) {
        SpringApplication.run(EndUserResourceServiceApplication.class, args);
    }   
}

Auth服务器:

@SpringBootApplication
@RestController
@EnableResourceServer
public class ApiAuthServerApplication  extends ResourceServerConfigurerAdapter {

    @Configuration
    @EnableWebSecurity
    @Order(-10)
    protected static class LoginConfig extends WebSecurityConfigurerAdapter {

        @Autowired
        private CustomUserDetailsService userDetailsService;

        @Bean(name = "authenticationManagerBean")
        @Override       
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }

        @Override
        @Autowired
        public void configure(AuthenticationManagerBuilder auth) throws Exception {                 
            auth
            .userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder());                
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {          
            http            
            .formLogin().permitAll()
            .and()
            .requestMatchers().antMatchers("/login", "/oauth/authorize", "/oauth/confirm_access")               
            .and()
            .authorizeRequests().anyRequest().authenticated();
        }

        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }

    @Configuration
    @EnableAuthorizationServer
    protected static class OAuth2Config extends AuthorizationServerConfigurerAdapter {

        @Autowired
        private TokenStore tokenStore;

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

        @Autowired
        private CustomUserDetailsService userDetailsService;

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

        @Override
        public void configure(ClientDetailsServiceConfigurer clients) throws Exception {            

            clients.inMemory()
            .withClient("my-client")    
            .secret("our_s3cret")
            .authorities("ROLE_CLIENT")         
            .authorizedGrantTypes("implicit", "password", "refresh_token")
            .redirectUris("http://anywhere")
            .scopes("read")
            .autoApprove(true);
        }

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

    public static void main(String[] args) {
        SpringApplication.run(ApiAuthServerApplication.class, args);
    }

    @RequestMapping("/user")
    public Principal user(Principal user) {
        return user;
    }
}

要点:

  1. 我可以使用user-info-uri来验证访问令牌并使用&#34; hasRole&#34;
  2. 使用单独的资源服务器和授权服务器时是否有必要使用共享数据库进行令牌存储?

1 个答案:

答案 0 :(得分:0)

我最终使用的是共享令牌存储,目前效果很好