Чтобы решить эту проблему, я добавил идентификатор пользователя в токене от шлюза к каждому микросервису.
Вот как я решил это в сгенерированном коде 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.");
}
Любые отзывы приветствуются.