如何使用 spring-session 和 spring-security-oauth 保护同一个资源
How to protect the same resource using both spring-session and spring-security-oauth
我有使用两种身份验证的要求,
对于网络,我们使用@EnableRedisHttpSession,对于移动设备等其他消费者,我们使用@EnableAuthorizationServer 和@EnableResourceServer。
假设我们尝试保护两种身份验证机制共有的控制器,例如 /api/v1/test
我遇到了障碍。
我只能使用一种身份验证方案
如果我设置@WebSecurityConfigurerAdapter @order(2) 和@ResourceServerConfigurerAdapter @order(3) 那么我只能通过网络访问资源
如果我设置@ResourceServerConfigurerAdapter @order(2) 和@WebSecurityConfigurerAdapter @order(3),那么只有 OAuth 有效。
我无法同时使用这两种机制 time.how 我们能否让两者一起工作,例如,如果请求来自网络,则使用负责该机制的过滤器,如果请求来自移动设备使用适当的过滤器。 web 使用 cookie,API 消费者使用 Authorization : Bearer header。
请帮忙
听起来很奇怪。我建议您回顾一下 REST API 的使用方式以及浏览器用户应该使用它的原因。最好将 Web 视图和 REST 分开 API,不要混用。
但是,回答您的问题“我可以同时对某些 URI 使用两种身份验证吗”- 是的,您可以。
您需要自定义 RequestMatcher
来决定如何路由传入请求。
所以:
- 对于“API 消费者”- 检查是否存在
Authorization
header
包含“承载”
- 对于“浏览器用户”- 只需反转第一条规则
代码示例:
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);
}
- OAuth2 身份验证
@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 安全架构的文章,以了解其工作原理:
https://spring.io/guides/topicals/spring-security-architecture/#_web_security
我有使用两种身份验证的要求, 对于网络,我们使用@EnableRedisHttpSession,对于移动设备等其他消费者,我们使用@EnableAuthorizationServer 和@EnableResourceServer。
假设我们尝试保护两种身份验证机制共有的控制器,例如 /api/v1/test
我遇到了障碍。 我只能使用一种身份验证方案 如果我设置@WebSecurityConfigurerAdapter @order(2) 和@ResourceServerConfigurerAdapter @order(3) 那么我只能通过网络访问资源
如果我设置@ResourceServerConfigurerAdapter @order(2) 和@WebSecurityConfigurerAdapter @order(3),那么只有 OAuth 有效。
我无法同时使用这两种机制 time.how 我们能否让两者一起工作,例如,如果请求来自网络,则使用负责该机制的过滤器,如果请求来自移动设备使用适当的过滤器。 web 使用 cookie,API 消费者使用 Authorization : Bearer header。
请帮忙
听起来很奇怪。我建议您回顾一下 REST API 的使用方式以及浏览器用户应该使用它的原因。最好将 Web 视图和 REST 分开 API,不要混用。
但是,回答您的问题“我可以同时对某些 URI 使用两种身份验证吗”- 是的,您可以。
您需要自定义 RequestMatcher
来决定如何路由传入请求。
所以:
- 对于“API 消费者”- 检查是否存在
Authorization
header 包含“承载” - 对于“浏览器用户”- 只需反转第一条规则
代码示例:
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);
}
- OAuth2 身份验证
@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 安全架构的文章,以了解其工作原理:
https://spring.io/guides/topicals/spring-security-architecture/#_web_security