【问题标题】:Spring OAuth2, access ROLE with userInfoUri?Spring OAuth2,使用 userInfoUri 访问角色?
【发布时间】:2015-12-19 11:01:48
【问题描述】:

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

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 资源时,我得到一个拒绝访问的异常,并且在日志中我看到:

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 = "ROLE_USER"。这是哪里来的,不应该是“ROLE_END_USER”吗?

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

资源服务器:

@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);
    }   
}

认证服务器:

@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 来验证访问令牌并使用“hasRole”
  2. 使用单独的资源服务器和授权服务器时,是否需要使用共享数据库进行令牌存储?

【问题讨论】:

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


    【解决方案1】:

    我最终使用了一个共享令牌存储,目前效果很好

    【讨论】:

    • /user 如何知道如何处理令牌?这是在哪里定义的?
    猜你喜欢
    • 2017-05-22
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 2015-11-12
    • 2016-05-13
    • 2018-05-06
    相关资源
    最近更新 更多