如何使用 Webflux 在 Spring API 处理程序方法中访问 JWT 声明?
How can I access JWT claims in Spring API handler methods using Webflux?
我正在添加 WebFilter 以在 SecurityWebFilterChain 内部执行 JWT 身份验证。我们在 JWT 中对许多 API 端点所需的大量非身份验证相关信息进行了编码,因此我需要能够从 JWT 中提取信息并在我的 [=22= 中访问该信息] 处理程序方法(例如,LoginController.java)。实现此目标的最佳模式是什么?
这是我的 SecurityWebFilterChain,显示了 WebFilter 身份验证:
@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);
}
}
我会创建一个自定义的 Authentication
object 并在其中存储所需的信息。
对于 user-related 数据,存储在其 Principal
.For the non user-related data , sounds like Details
中是一个很好的存储位置。
许多 built-in AuthenticationProvider
将创建一个 UserDetails
并存储到 Principal
。这意味着如果您正在使用 built-it AuthenticationProvider
.
,您可以考虑只创建一个 customsied UserDetails
所以根据你实现认证逻辑的方式,你需要自定义相关的AuthenticationProvider
或Filter
等。目的是访问HttpServletRequest
,从HTTP header ,解析 JWT ,设置和配置此自定义 Authentication
object 并将其设置为 SecurityContext
:
SecurityContextHolder.getContext().setAuthentication(authenication);
要在 Controller 中访问此 Authentication
object,您可以使用:
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);
}
我正在添加 WebFilter 以在 SecurityWebFilterChain 内部执行 JWT 身份验证。我们在 JWT 中对许多 API 端点所需的大量非身份验证相关信息进行了编码,因此我需要能够从 JWT 中提取信息并在我的 [=22= 中访问该信息] 处理程序方法(例如,LoginController.java)。实现此目标的最佳模式是什么?
这是我的 SecurityWebFilterChain,显示了 WebFilter 身份验证:
@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);
}
}
我会创建一个自定义的 Authentication
object 并在其中存储所需的信息。
对于 user-related 数据,存储在其 Principal
.For the non user-related data , sounds like Details
中是一个很好的存储位置。
许多 built-in AuthenticationProvider
将创建一个 UserDetails
并存储到 Principal
。这意味着如果您正在使用 built-it AuthenticationProvider
.
UserDetails
所以根据你实现认证逻辑的方式,你需要自定义相关的AuthenticationProvider
或Filter
等。目的是访问HttpServletRequest
,从HTTP header ,解析 JWT ,设置和配置此自定义 Authentication
object 并将其设置为 SecurityContext
:
SecurityContextHolder.getContext().setAuthentication(authenication);
要在 Controller 中访问此 Authentication
object,您可以使用:
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);
}