如何使用Webflux在Spring API处理程序方法中访问JWT声明?

时间:2019-05-24 21:54:36

标签: java spring spring-security spring-security-oauth2 spring-webflux

我要在SecurityWebFilterChain内部添加一个WebFilter来执行JWT身份验证。我们在许多API端点所需的JWT中编码了许多与非身份验证相关的信息,因此我需要能够从JWT中提取信息并在我的API处理程序方法(例如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);
    }
}

1 个答案:

答案 0 :(得分:1)

我将创建一个自定义的Authentication对象,并将所需的信息存储在其中。

对于与用户相关的数据,请将其存储在Principal内。对于与非用户相关的数据,听起来Details就是一个好地方。

许多内置AuthenticationProvider将创建一个UserDetails并存储到Principal。这意味着,如果您使用的是内置UserDetails,则可以考虑创建定制化的AuthenticationProvider

因此,根据实现身份验证逻辑的方式,您需要自定义相关的AuthenticationProviderFilter等。目的是访问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);
    }