我要在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);
}
}
答案 0 :(得分:1)
我将创建一个自定义的Authentication
对象,并将所需的信息存储在其中。
对于与用户相关的数据,请将其存储在Principal
内。对于与非用户相关的数据,听起来Details
就是一个好地方。
许多内置AuthenticationProvider
将创建一个UserDetails
并存储到Principal
。这意味着,如果您使用的是内置UserDetails
,则可以考虑创建定制化的AuthenticationProvider
。
因此,根据实现身份验证逻辑的方式,您需要自定义相关的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);
}