@Configuration
@EnableResourceServer
public class ResourceServerConfigurationextends ResourceServerConfigurerAdapter {
private static final StringUSER_RESOURCE_ID ="user";
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
// 如果关闭 stateless,则 accessToken 使用时的 session id 会被记录,
// 后续请求不携带 accessToken 也可以正常响
resources.resourceId(USER_RESOURCE_ID).stateless(true);
}
@Override
public void configure(HttpSecurity http)throws Exception {
http.requestMatchers()
// 保险起见,防止被主过滤器链路拦截
.antMatchers("/user/**")
.and()
.authorizeRequests().anyRequest().authenticated()
.and()
.authorizeRequests()
.antMatchers("/user/info").access("#oauth2.hasScope('get_user_info')")
.antMatchers("/user/me").access("#oauth2.hasScope('get_user_me')")
;
}
}
最近在使用spring的Security oauth2接入第三方程序时,在授权时 scope设置为get_user_me,在获取token后,为什么可以访问/user/info?
后来发现其中会调用FilterInvocationSecurityMetadataSource的方法来获取被拦截url所需的全部权限。而我将token跟在url后面,导致匹配不上,所以并没有起作用。
于是乎我只是将token放在header里就好了,要这样放
Authorization:Bearer+token ,否则解析不出来token的。
下一步,在调用授权管理器AccessDecisionManager,这个授权管理器会通过spring的全局缓存SecurityContextHolder获取用户的权限信息,还会获取被拦截的url和被拦截url所需的全部权限,然后根据所配的策略,如果权限足够,则返回,权限不够则报错并调用权限不足页面。