Spring Security OAuth2 架构上分为Authorization Server和Resource Server。我们可以为每一个Resource Server(一个微服务实例)设置一个resourceid。再给client授权的时候,可以设置这个client可以访问哪一些微服务实例,如果没设置,就是对所有的resource都有访问权限。
在每个ResourceServer实例上设置。
经测试,这个不管用,原因待查。
security:
enable-csrf: false
oauth2:
resource:
id: resource1
jwt:
key-uri: http://authorization-server:8080/oauth/token_key
filter-order: 3
@Configuration
@EnableResourceServer
@EnableOAuth2Client
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter{
private static final String DEMO_RESOURCE_ID = "resource1";
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(DEMO_RESOURCE_ID).stateless(true);
}
}
@EnableResourceServer会给Spring Security的FilterChan添加一个OAuth2AuthenticationProcessingFilter,OAuth2AuthenticationProcessingFilter会使用OAuth2AuthenticationManager来验证token。
OAuth2AuthenticationManager#authenticate(Authentication authentication)
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (authentication == null) {
throw new InvalidTokenException("Invalid token (token not found)");
}
String token = (String) authentication.getPrincipal();
OAuth2Authentication auth = tokenServices.loadAuthentication(token);
if (auth == null) {
throw new InvalidTokenException("Invalid token: " + token);
}
Collection<String> resourceIds = auth.getOAuth2Request().getResourceIds();
if (resourceId != null && resourceIds != null && !resourceIds.isEmpty() && !resourceIds.contains(resourceId)) {
throw new OAuth2AccessDeniedException("Invalid token does not contain resource id (" + resourceId + ")");
}
checkClientDetails(auth);
if (authentication.getDetails() instanceof OAuth2AuthenticationDetails) {
OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();
// Guard against a cached copy of the same details
if (!details.equals(auth.getDetails())) {
// Preserve the authentication details from the one loaded by token services
details.setDecodedDetails(auth.getDetails());
}
}
auth.setDetails(authentication.getDetails());
auth.setAuthenticated(true);
return auth;
}
下面这段便是验证resourceid的地方;
Collection<String> resourceIds = auth.getOAuth2Request().getResourceIds();
if (resourceId != null && resourceIds != null && !resourceIds.isEmpty() && !resourceIds.contains(resourceId)) {
throw new OAuth2AccessDeniedException("Invalid token does not contain resource id (" + resourceId + ")");
}
在Spring Security的FilterChain中,OAuth2AuthenticationProcessingFilter在FilterSecurityInterceptor的前面,所以会先验证client有没有此resource的权限,只有在有此resource的权限的情况下,才会再去做进一步的判断;