Jhipster Microservices - Правильный способ получить UserId в Microservices? - PullRequest
0 голосов
/ 31 октября 2018

Я использую шлюз JHipster с JWT и у меня есть микросервис.

Когда переадресация вызова переадресовывается со шлюза на микросервис в бизнес-классе микросервиса, я хочу получить идентификатор пользователя, прошедшего проверку подлинности.

Причина этого в том, что я хочу сохранить его в БД с сущностью, чтобы данные одного пользователя могли быть полностью отделены от данных другого пользователя (и пользователь не может обновить данные другого пользователя ... и т. Д.).

Хотя я могу получить зарегистрированное имя пользователя, у меня нет идентификатора пользователя.

Как правильно решить эту проблему:

  • вызывать шлюз из микросервиса?

(для меня это не имеет особого смысла, поскольку шлюз вызывает службу, и я хочу знать эту информацию для большинства служб).

  • обновить TokenProvider в шлюзе, чтобы включить идентификатор пользователя? (не уверен, как это сделать). Это правильный подход?

  • есть еще предложения?

Спасибо, Fergal.

Примечание: я вижу другие подобные вопросы. Это не повторяющийся вопрос. Не отмечайте это как дубликат, если не уверены абсолютно. Примечание - я использую JWT

1 Ответ

0 голосов
/ 01 ноября 2018

Чтобы решить эту проблему, я добавил идентификатор пользователя в токене от шлюза к каждому микросервису.

Вот как я решил это в сгенерированном коде JHipster:

В шлюзе добавьте UserService к UserJWTController, получите идентификатор пользователя и используйте его при создании токена.

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";

и затем в моем приложении для микросервиса я сделал это:

создал новый класс:

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;
        });
 }

и, наконец, теперь я могу вызывать этот метод из любого бизнес-класса:

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

Любые отзывы приветствуются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...