【问题标题】:How can I access JWT claims in Spring API handler methods using Webflux?如何使用 Webflux 在 Spring API 处理程序方法中访问 JWT 声明?
【发布时间】: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);
    }
}

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-31
      • 2020-03-31
      • 2018-10-31
      • 1970-01-01
      • 2015-10-09
      • 2016-08-11
      • 2018-12-17
      • 2022-01-01
      相关资源
      最近更新 更多