我要求使用两种身份验证, 对于web我们@EnableRedisHttpSession和其他消费者,比如移动我们使用@EnableAuthorizationServer和@EnableResourceServer。
假设我们尝试保护两个身份验证机制共同的控制器,例如/ api / v1 / test
我遇到了障碍。 我只能使用一种身份验证方案 如果我设置@WebSecurityConfigurerAdapter @order(2)和@ResourceServerConfigurerAdapter @order(3)那么我只能通过网络访问资源
如果我设置@ResourceServerConfigurerAdapter @order(2)和@WebSecurityConfigurerAdapter @order(3),那么只有OAuth可以工作。
我无法同时使用这两种机制。我们可以让两者一起工作,例如,如果请求来自Web使用负责该过滤器的过滤器,并且如果请求来自移动设备,则使用适当的过滤器。 web使用cookie和API使用者使用Authorization:Bearer标题。
请帮助
答案 0 :(得分:2)
这听起来很奇怪。我建议您查看REST API的使用方式以及浏览器用户应该如何使用它。最好将Web视图和REST API分开,不要混用它。
无论如何,作为您问题的答案“我可以同时对某些URI使用两种身份验证” - 是的,您可以。
为此,您需要一个自定义RequestMatcher
来决定如何路由传入的请求。
所以:
Authorization
标题的存在
包含“Bearer”代码示例:
public abstract class AntPathRequestMatcherWrapper implements RequestMatcher {
private AntPathRequestMatcher delegate;
public AntPathRequestMatcherWrapper(String pattern) {
this.delegate = new AntPathRequestMatcher(pattern);
}
@Override
public boolean matches(HttpServletRequest request) {
if (precondition(request)) {
return delegate.matches(request);
}
return false;
}
protected abstract boolean precondition(HttpServletRequest request);
}
@EnableResourceServer
@Configuration
public class ResourceServerConfigurer extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new AntPathRequestMatcherWrapper("/api/v1/test") {
@Override
protected boolean precondition(HttpServletRequest request) {
return String.valueOf(request.getHeader("Authorization")).contains("Bearer");
}
}).authorizeRequests().anyRequest().authenticated();
}
}
@Configuration
@EnableWebSecurity
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatcher(new AntPathRequestMatcherWrapper("/api/v1/test") {
@Override
protected boolean precondition(HttpServletRequest request) {
return !String.valueOf(request.getHeader("Authorization")).contains("Bearer");
}
}).authorizeRequests().anyRequest().authenticated();
}
}
使用此配置,可以为一个URI /api/v1/test
使用两种不同的身份验证类型。
此外,我强烈建议阅读Dave Syer关于Spring Security架构的文章,了解它是如何工作的:
https://spring.io/guides/topicals/spring-security-architecture/#_web_security