Jhipster 微服务 - 在微服务中获取 UserId 的正确方法?

Jhipster Microservices - Correct way to get UserId in Microservices?

我正在将 JHipster 的网关与 JWT 一起使用,并且我有一个微服务。

当rest调用从网关转发到微服务时,在微服务业务class中,我想获取认证用户的用户id。

这样做的原因是我想将它与实体一起保存在数据库中,以便一个用户的数据可以与其他用户的数据完全分开(并且一个用户不能更新另一个用户的数据......等等......) .

虽然我可以得到登录的用户名,但我没有用户id。

解决这个问题的正确方法是什么:

(这对我来说意义不大,因为网关正在调用该服务,我想知道大多数服务的此信息)。

谢谢, 弗加尔.

注:我看到其他类似的问题。这不是一个重复的问题。除非绝对确定,否则不要将此标记为重复。注意 - 我正在使用 JWT

为了解决这个问题,我在网关的令牌中添加了用户 ID 到每个微服务。

以下是我在 JHipster 生成的代码中解决这个问题的方法:

在Gateway中,将UserService添加到UserJWTController中,并获取用户id,以及 在创建令牌时使用它。

public ResponseEntity<JWTToken> authorize(@Valid @RequestBody LoginVM loginVM) {
    ...
    ...
    Optional<User> user = userService.getUserWithAuthoritiesByLogin(loginVM.getUsername());
    Long userId = user.get().getId();
    String jwt = tokenProvider.createToken(authentication, rememberMe, userId);
    ...

将声明添加到令牌:

  claim(USER_ID_KEY, userId)

注意,我将此添加到令牌提供程序:

  private static final String USER_ID_KEY = "userId";

然后在我的 微服务应用程序 中,我这样做了:

创建了一个新的 class:

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;

import java.util.Collection;

public class SamAuthenticationToken extends UsernamePasswordAuthenticationToken {

public Long getUserId() {
    return userId;
}

private final Long userId;

public SamAuthenticationToken(Object principal, Object credentials, Long userId) {
    super(principal, credentials);
    this.userId = userId;
}

public SamAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities, Long userId) {
    super(principal, credentials, authorities);
    this.userId = userId;
}
}

然后我更改了 TokenProvider.getAuthentication 以添加以下行:

    Long userId = null;
    Object userIdObj = claims.get(USER_ID_KEY);
    if (userIdObj != null) {
        String userIdStr = userIdObj.toString();
        userId = Long.parseLong(userIdStr);
        log.debug("Claim--> {}", userId);
    } else {
        log.debug("No user id in token");
    }

    User principal = new User(claims.getSubject(), "", authorities);
    return new SamAuthenticationToken(principal, token, authorities, userId);

然后我向 SecurityUtils 添加了一个新方法

 public static Optional<Long> getUserId() {
    SecurityContext securityContext = SecurityContextHolder.getContext();
    return Optional.ofNullable(securityContext.getAuthentication())
        .map(authentication -> {
            if (authentication instanceof SamAuthenticationToken) {
                SamAuthenticationToken samAuthenticationToken = (SamAuthenticationToken) authentication;
                return samAuthenticationToken.getUserId();
            }
            return null;
        });
 }

最后,我现在可以从任何企业调用此方法 class:

    Optional<Long> userId = SecurityUtils.getUserId();
    if (userId.isPresent()) {
        log.info("User Id--->{}", userId.get());
    } else {
        log.info("No userId present.");
    }

欢迎任何反馈。