如何使用 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

所以根据你实现认证逻辑的方式,你需要自定义相关的AuthenticationProviderFilter等。目的是访问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);
    }