spring security permitAll 仍在考虑在 Authorization 标头中传递的令牌,如果令牌无效则返回 401
Posted
技术标签:
【中文标题】spring security permitAll 仍在考虑在 Authorization 标头中传递的令牌,如果令牌无效则返回 401【英文标题】:spring security permitAll still considering token passed in Authorization header and returns 401 if token is invalid 【发布时间】:2016-07-17 18:00:40 【问题描述】:我在我的项目中使用 spring security oauth。我通过在 spring security ResourceServerConfigurerAdapter 中进行配置,从身份验证中排除了一些 url。我加了http.authorizeRequests().antMatchers(url).permitAll()
。
现在,我看到的是,如果我不将 Authorization 标头传递给这些 url,它就不会经过身份验证。并且 API 被正确调用。
如果使用 Authorization 标头进行调用,则它会验证令牌,如果令牌未被验证,则调用失败。
我的问题是我需要做什么才能在我拥有 permitAll 的请求中忽略令牌。
【问题讨论】:
【参考方案1】:Spring OAuth2 将拦截所有带有 header: Authorization Bearer xxx 的 url。
为了避免 Spring OAuth2 拦截 url。我创建了一个比 Spring OAuth2 配置更高阶的 SecurityConfiguration。
@Configuration
@EnableWebSecurity
@Order(1) // this is important to run this before Spring OAuth2
public class SecurityConfiguration extends WebSecurityConfigurerAdapter
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception
return super.authenticationManagerBean();
@Override
protected void configure(HttpSecurity http) throws Exception
List<RequestMatcher> requestMatchers = new ArrayList<RequestMatcher>();
// allow /api/public/product/** and /api/public/content/** not intercepted by Spring OAuth2
requestMatchers.add(new AntPathRequestMatcher("/api/public/product/**"));
requestMatchers.add(new AntPathRequestMatcher("/api/public/content/**"));
http
.requestMatcher(new OrRequestMatcher(requestMatchers))
.authorizeRequests()
.antMatchers("/api/public/product/**", "/api/public/content/**").permitAll()
以上配置允许 /api/public/product/** 和 /api/public/content/** 由该配置处理,而不是由 Spring OAuth2 处理,因为该配置具有更高的@Order。
因此,即使将无效令牌设置为上述api调用也不会导致无效的访问令牌。
【讨论】:
但是如果token是有效的,你就无法获得认证用户。 @meobeo173 是的,正如你所说,我无法从 auth-server 获取 userInfo。所以,我将user-info-url
端点切换到 api-server。
@meobeo173 我正在使用spring-oauth2
和spring-boot
设置。但是我创建了 url 以在我的身份验证服务器上获取经过身份验证的用户信息 (security.oauth2.resource.user-info-uri
)。在我将我的 spring-security 配置类的顺序更改为1
之前可以,正如这个答案所描述的那样。因此,我将 user-info-uri
端点移到了我的 api-server
,它为来自 auth-server
应用程序的休息服务提供服务。【参考方案2】:
根据 spring-oauth2 文档https://projects.spring.io/spring-security-oauth/docs/oauth2.html
注意:如果您的授权服务器也是资源服务器,那么还有另一个具有较低优先级的安全过滤器链来控制 API 资源。对于那些受访问令牌保护的请求,您需要它们的路径不与主要面向用户的过滤器链中的路径匹配,因此请确保在上面的 WebSecurityConfigurer 中包含一个仅挑选非 API 资源的请求匹配器。
所以定义 WebSecurityConfigurer 实现的顺序比 ResourceServerConfig 更高。
【讨论】:
你能详细解释一下粗体字吗?我的意思是,如果有另一个优先级较低的安全过滤器链,为什么它可以控制 API 资源?如果我们为非 API 资源维护一个 WebSecurityConfigurer,那么这些非 API 资源是什么? @hermantvsn【参考方案3】:如果您正在处理 Reactive Spring webflux,来自 SooCheng Koh 的回答。
@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
@Order(1) // this is important to run this before Spring OAuth2
public class PublicSecurityConfiguration
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http)
http
.authorizeExchange()
.pathMatchers("/api/public/**").permitAll();
return http.build();
【讨论】:
以上是关于spring security permitAll 仍在考虑在 Authorization 标头中传递的令牌,如果令牌无效则返回 401的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security Oauth2 permitAll()方法小记
Spring Security permitAll 不适用于某些端点
升级到 Spring Boot 2.0.2 后 Spring Security .permitAll() 不再有效
Spring Security - permitAll() 不允许未经身份验证的访问