我正在使用Spring Security使用jwt令牌对用户进行身份验证。
当令牌格式错误或过期时,身份验证正常,我得到403 Http状态,如以下配置所示:
@Bean
public SecurityWebFilterChain securitygWebFilterChain(ServerHttpSecurity http) {
return http
.exceptionHandling()
.authenticationEntryPoint((swe, e) -> {
return Mono.fromRunnable(() -> {
swe.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
});
}).accessDeniedHandler((swe, e) -> {
return Mono.fromRunnable(() -> {
swe.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
});
}).and()
.csrf().disable()
.formLogin().disable()
.httpBasic().disable()
.authenticationManager(authenticationManager)
.securityContextRepository(securityContextRepository)
.authorizeExchange()
.pathMatchers(HttpMethod.OPTIONS).permitAll()
.pathMatchers("/**").permitAll()
.anyExchange().authenticated()
.and().build();
}
但是,当我使用Spring安全上下文中的Principal或Authentication从jwt令牌中获取用户信息时,如以下代码所示:
@ResponseStatus(HttpStatus.OK)
@GetMapping("/me")
public Mono<ClientDTO> find(final Principal principal) {
return this.clientService.findByMail(principal.getName());
}
如果令牌格式不正确或已过期,我会从Principal对象得到一个空指针异常,并显示500 https状态。
答案 0 :(得分:3)
如果我的回答无法解决您的问题,我想立即道歉,因为我看不到您的所有代码。
我有一个合适的项目,我可以在类似的条件下检查Principal对象的工作,并且一切对我都有效。因此,问题不在于此。
您可能在令牌验证方法中引发了异常。像这样的东西:
public boolean validateToken(String token) {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
return true;
} catch (JwtException | IllegalArgumentException e) {
throw new JwtAuthenticationException("JWT token is expired or invalid", e);
}
}
在这种情况下,在配置中捕获异常之前就已将其捕获。解决方案可能是拒绝令牌验证方法中的新异常,以便将信息输出到日志:
public boolean validateToken(String authToken) {
try {
Jwts.parser().setSigningKey(key).parseClaimsJws(authToken);
return true;
} catch (io.jsonwebtoken.security.SecurityException | MalformedJwtException e) {
log.info("Invalid JWT signature.");
log.trace("Invalid JWT signature trace: {}", e);
} catch (ExpiredJwtException e) {
log.info("Expired JWT token.");
log.trace("Expired JWT token trace: {}", e);
} catch (UnsupportedJwtException e) {
log.info("Unsupported JWT token.");
log.trace("Unsupported JWT token trace: {}", e);
} catch (IllegalArgumentException e) {
log.info("JWT token compact of handler are invalid.");
log.trace("JWT token compact of handler are invalid trace: {}", e);
}
return false;
}
如果能帮到您,我会很高兴。否则,我需要有关您的代码的更多信息。
答案 1 :(得分:0)
@ResponseStatus(HttpStatus.OK)
@GetMapping("/me")
public Mono<ClientDTO> find(final Principal principal) {
if(principal!=null) return this.clientService.findByMail(principal.getName());
else throw new CustomTokenExpiredException();
}
并删除
.pathMatchers("/**").permitAll()