【发布时间】: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;
}
}
总结:
- 我可以使用 user-info-uri 来验证访问令牌并使用“hasRole”
- 使用单独的资源服务器和授权服务器时,是否需要使用共享数据库进行令牌存储?
【问题讨论】:
标签: spring-security spring-boot spring-security-oauth2