【问题标题】:How get jwt 'user_name' inside @ExceptionHandler class ResponseEntity using WebRequest (Spring)?如何使用 WebRequest (Spring) 在 @ExceptionHandler 类 ResponseEntity 中获取 jwt 'user_name'?
【发布时间】:2021-02-25 16:09:23
【问题描述】:

我试试: How to get the current logged in user object from spring security?

但不起作用。

如何将org.springframework.security.oauth2.jwt.Jwt@9f4f7d6e转换为用户名jwt?

我的课程开始于:

@Slf4j
@RestControllerAdvice
public class RestControllerExceptionHandler {

    @ExceptionHandler(Throwable.class)
    public final ResponseEntity<ErrorResponse> handleException(Throwable ex, WebRequest request) {
        // ex.printStackTrace();
        // Authentication authenticantion = SecurityContextHolder.getContext().getAuthentication();
        String username = new String();
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();

        AbstractAuthenticationToken auth = (AbstractAuthenticationToken)
                SecurityContextHolder.getContext().getAuthentication();

        UserDetails details = (UserDetails) auth.getDetails();

        log.error(ex.getMessage().toUpperCase() + " User:  "+ username  + " Source: " + request.getDescription(false));
....

【问题讨论】:

  • 将原始 Jwt 包含为 Spring Principal 对象的内容不是一个好主意,因为您的其余代码将处理外部格式以提取安全信息和相关数据(因为您必须目前做)。更好的方法是将提供的安全信息转换为标准的Authentication 对象(可能您正在将其转换为自己的安全过滤器)。这样,如果您修改内部 Jwt 令牌或使用其他安全选项,“您的代码的其余部分”将不会改变。

标签: java spring spring-security jwt


【解决方案1】:

如果您只需要用户名,那么您可以从request.getRemoteUser() 访问它。或者,您也可以从request.getUserPrincipal().getName() 获取用户名。如果您不需要WebRequest,您可以改为将您的签名更改为:

@ExceptionHandler(Throwable.class)
public final ResponseEntity<ErrorResponse> handleException(Throwable ex, Principal principal) {
    String username = principal.getName();

您也可以使用@AuthenticationPrincipal 获取Jwt

@ExceptionHandler(Throwable.class)
public final ResponseEntity<ErrorResponse> handleException(Throwable ex, @AuthenticationPrincipal Jwt jwt) {
    String username = jwt.getClaim("user_name");

你也应该能够做这样的事情:

@ExceptionHandler(Throwable.class)
public final ResponseEntity<ErrorResponse> handleException(Throwable ex, @AuthenticationPrincipal(expression = "claims['user_name']") String username) {

最后,如果你经常使用上面的代码,你可以使用类似的东西:

@Target({ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@AuthenticationPrincipal(expression = "claims['user_name']")
public @interface CurrentUsername {}

然后你可以通过以下方式访问它:

@ExceptionHandler(Throwable.class)
public final ResponseEntity<ErrorResponse> handleException(Throwable ex, @CurrentUsername String username) {

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-16
    • 2018-11-10
    • 2020-07-20
    • 2015-12-28
    • 2018-09-11
    • 1970-01-01
    • 2018-11-25
    • 2019-03-02
    相关资源
    最近更新 更多