如何使用 Webflux 在 Spring API 处理程序方法中访问 JWT 声明?
Posted
技术标签:
【中文标题】如何使用 Webflux 在 Spring API 处理程序方法中访问 JWT 声明?【英文标题】:How can I access JWT claims in Spring API handler methods using Webflux? 【发布时间】:2019-10-11 11:39:50 【问题描述】:我正在添加一个 WebFilter 以在 SecurityWebFilterChain 内执行 JWT 身份验证。我们在 JWT 中编码了许多 API 端点所需的与身份验证无关的信息,因此我需要能够从 JWT 中提取信息并在我的 API 处理程序方法(例如 LoginController.爪哇)。实现这一目标的最佳模式是什么?
这是显示 WebFilter 身份验证的 SecurityWebFilterChain:
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http)
return http
.authorizeExchange()
.pathMatchers("/login", "/")
.authenticated()
.and()
.addFilterAt(basicAuthenticationFilter(), SecurityWebFiltersOrder.HTTP_BASIC)
.authorizeExchange()
.pathMatchers("/adm")
.authenticated()
.and()
.addFilterAt(basicAuthenticationFilter(), SecurityWebFiltersOrder.HTTP_BASIC)
.authorizeExchange()
.pathMatchers("/api/**")
.access(authorizationManager)
.and()
.addFilterAt(bearerAuthenticationFilter(), SecurityWebFiltersOrder.AUTHENTICATION)
.build();
这是我想在 LoginController.java 中访问声明的地方:
@RestController()
@RequestMapping(value = "/login")
public class LoginController
private final UserMongoRepository repository;
@Autowired
public LoginController(UserMongoRepository repository)
this.repository = repository;
@PostMapping("")
public Mono<User> login(@RequestBody User post,
@RequestParam String user_id,
@RequestParam String username)
//Need to access information from JWT claims here
return this.repository.findById(user_id);
【问题讨论】:
【参考方案1】:我会创建一个自定义的Authentication
对象并将所需的信息存储在其中。
对于用户相关的数据,存储在其Principal
中。对于非用户相关的数据,听起来Details
是一个存储的好地方。
许多内置的AuthenticationProvider
将创建一个UserDetails
并存储到Principal
。这意味着如果您使用的是内置的AuthenticationProvider
,则可以考虑创建一个定制的UserDetails
。
所以根据你实现认证逻辑的方式,你需要自定义相关的AuthenticationProvider
或Filter
等。目的是访问HttpServletRequest
,从HTTP头中获取JWT,解析JWT,设置并配置这个自定义的Authentication
对象并将其设置为SecurityContext
:
SecurityContextHolder.getContext().setAuthentication(authenication);
要在 Controller 中访问这个 Authentication
对象,您可以使用:
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
CurrentUser user = (CurrentUser) auth.getPrincipal();
CurrentRequestDetail detail= (CurrentRequestDetail) auth.getDetails();
/** CurrentUser and CurrentRequestDetail is the customised Principal and Details**/
如果你只需要访问[Principal
],你可以使用@AuthenticationPrincipal
:
@PostMapping("")
public Mono<User> login(@RequestBody User post,
@RequestParam String user_id,
@RequestParam String username,
@AuthenticationPrincipal CurrentUser currentUser)
//Need to access information from JWT claims here
return this.repository.findById(user_id);
【讨论】:
以上是关于如何使用 Webflux 在 Spring API 处理程序方法中访问 JWT 声明?的主要内容,如果未能解决你的问题,请参考以下文章
覆盖 Spring webflux 项目的默认 Threadpool 执行器的效果如何?
在没有 servlet api 的 webflux 项目中使用 OAuth2 和 Spring Security OAuth2 和 reactor netty