您的当前位置:首页正文

Spring Security OAuth2#resource_ids

2024-11-30 来源:个人技术集锦

发博词

Spring Security OAuth2 架构上分为Authorization Server和Resource Server。我们可以为每一个Resource Server(一个微服务实例)设置一个resourceid。再给client授权的时候,可以设置这个client可以访问哪一些微服务实例,如果没设置,就是对所有的resource都有访问权限。

ResourceID在哪设置

在每个ResourceServer实例上设置。

配置文件

经测试,这个不管用,原因待查。

security: 
  enable-csrf: false
  oauth2: 
    resource: 
      id: resource1
      jwt: 
        key-uri: http://authorization-server:8080/oauth/token_key
      filter-order: 3 

ResourceServerConfigurerAdapter

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

ResourceID在哪验证

@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的权限的情况下,才会再去做进一步的判断;

显示全文