在同一请求中同时使用这两个配置可能会产生歧义。虽然有一些解决方案,但更清晰的方法是定义单独的请求组:
- OAuth2Sso:用于来自浏览器的用户,我们想要将他们重定向到身份验证提供者以获取令牌
- ResourceServer:通常用于API请求,使用他们从某个地方获得的令牌(最可能是从相同的身份验证提供者获得的)
为了实现这一点,请使用请求匹配器分离配置:
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Bean("resourceServerRequestMatcher")
public RequestMatcher resources() {
return new AntPathRequestMatcher("/resources/**");
}
@Override
public void configure(final HttpSecurity http) throws Exception {
http
.requestMatcher(resources()).authorizeRequests()
.anyRequest().authenticated();
}
}
同时从 SSO 过滤器链中排除这些内容:
@Configuration
@EnableOAuth2Sso
public class SsoSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("resourceServerRequestMatcher")
private RequestMatcher resources;
@Override
protected void configure(final HttpSecurity http) throws Exception {
RequestMatcher nonResoures = new NegatedRequestMatcher(resources);
http
.requestMatcher(nonResoures).authorizeRequests()
.anyRequest().authenticated();
}
}
并将所有资源放置在/resources/**
下。
当然,在这种情况下,两者都将使用相同的oauth2配置(accessTokenUri
,jwt.key-value
等)。
更新1:
实际上,您可以通过为上述配置使用此请求匹配器来实现原始目标:
new RequestHeaderRequestMatcher("Authorization")
更新2:
(对@sid-morad评论的解释)
Spring Security为每个配置创建一个过滤器链。每个过滤器链的请求匹配器按照配置的顺序进行评估。
WebSecurityConfigurerAdapter
的默认顺序为100,ResourceServerConfiguration
的默认顺序为3。这意味着ResourceServerConfiguration
的请求匹配器首先被评估。这些配置的顺序可以被覆盖,例如:
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Autowired
private org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfiguration configuration;
@PostConstruct
public void setSecurityConfigurerOrder() {
configuration.setOrder(3);
}
...
}
@Configuration
@EnableOAuth2Sso
@Order(100)
public class SsoSecurityConfiguration extends WebSecurityConfigurerAdapter {
...
}
所以,在上面的示例中,SsoSecurityConfiguration
不需要请求匹配器。但是知道背后的原因很好 :)
new NegatedRequestMatcher(resources)
部分是不必要的。 - SidMorad