oauth2资源服务器如何保护资源的

43 阅读2分钟

在配置资源服务器的时候,经常最简化的配置就是:

http.oauth2ResourceServer(oauth -> oauth.jwt(Customizer.withDefaults()))

这行代码底层主要配置了两大核心支柱:一个负责拦截,一个负责拆弹(解析 JWT)

1.BearerTokenAuthenticationFilter 负责拦截

在 OAuth2 资源服务器模式下,Spring Security 会在过滤器链中加入一个核心拦截器:BearerTokenAuthenticationFilter

  • 它的位置:通常在过滤器链的中后部。

  • 它的职责

    1. 扫描每个请求的 Header
    2. 寻找 Authorization: Bearer <TOKEN> 格式的头。
    3. 如果找到了,就把这一串长长的字符串(Token)提取出来,封装成一个 BearerTokenAuthenticationToken 对象,交给后续处理。

BearerTokenAuthenticationFilter拦截逻辑如下:

image.png

2.JwtAuthenticationProvider 负责拆弹(解析 JWT)

上图封装的BearerTokenAuthenticationToken要交给AuthenticationManager进行认证,AuthenticationManager使用AuthenticationProvider来完成校验,JwtAuthenticationProvider就是AuthenticationProvider接口的实现类,用来解析token

JwtAuthenticationProvider的源码如下图:

image.png

getJwt 就是利用jwtDecoder来完成对token的解析,生成Jwt对象

image.png

image.png image.png

利用JwtAuthenticationConverter,将Jwt对象转成最终的JwtAuthenticationToken

image.png

在这个过程中,底层还配置了一个权限转换器JwtGrantedAuthoritiesConverter

  • 默认逻辑:它会去找 JWT Payload 里的 scpscope 字段。
  • 结果:如果你的 JWT 里有 "scope": "read",那么在 Spring Security 内部,你的权限就会被自动转换成 SCOPE_read

如果不带token访问一个受保护的api会发生什么?

当你不带 Token 访问一个受保护的 API(如 /api/data)时,请求会流经过滤器链。

  • 过滤器BearerTokenAuthenticationFilter
  • 动作:它尝试从请求头 Authorization 中提取 Token。
  • 结果:它发现 Header 是空的。此时它什么都不做只是简单地把请求传给下一个过滤器。因为它的职责只是“提取”,没有 Token 意味着“当前用户依然是匿名状态”。

请求继续往后走,直到遇见 AuthorizationFilter(这是过滤器链的最后一关,负责最终权限判定)。

  • 逻辑:它发现你访问的是受保护资源,但目前的身份是 Anonymous(匿名)。
  • 动作:抛出一个 AccessDeniedException(拒绝访问异常)。

这个访问异常会被**ExceptionTranslationFilter** 这个过滤器处理

这个过滤器内部持有一个关键组件:AuthenticationEntryPoint。 对于 OAuth2,它的默认实现类是:BearerTokenAuthenticationEntryPoint

image.png

AuthenticationEntryPoint见名知意引导用户去认证的入口,用户尝试访问一个受保护的资源但尚未认证(即未登录)时,决定如何“开始”认证流程。

image.png

BearerTokenAuthenticationEntryPoint 专门用于 基于 Bearer Token(如 JWT)的无状态 REST API 认证场景

它的默认行为是:

返回 HTTP 状态码 401 Unauthorized,并在响应头中添加 WWW-Authenticate: Bearer

image.png

为什么会有 WWW-Authenticate: Bearer?

这是 RFC 6750 标准(OAuth 2.0 承载令牌)的规定。

• 含义:它在告诉客户端(比如你的前端 Vue 应用或 Postman):“这个资源是受保护的,你需要使用 Bearer Token 方案进行认证才能访问。”