Я установил претензии в токене JWT у поставщика токенов. теперь я хочу получить значение претензии через аутентификацию при попадании в API.
Я проверил Принципала, детали, учетные данные, органы власти, но я не получаю претензий ни по одному из них.
Claims claims = Jwts.claims().setSubject(authentication.getName());
claims.put(AUTHORITIES_KEY, authorities);
claims.put("userId", userRepo.findUserIdByUsername(authentication.getName()));
return Jwts.builder()
.setSubject(authentication.getName())
.setClaims(claims)
//.claim(AUTHORITIES_KEY, authorities)
.signWith(SignatureAlgorithm.HS512, SIGNING_KEY)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + ACCESS_TOKEN_VALIDITY_SECONDS*1000))
.compact();
Я хочу получить утверждение «userId» от аутентификации или любым другим способом получить значение утверждения из токена.




Это должно помочь.
Вы должны иметь возможность получать такие утверждения в своем контроллере.
var identity = HttpContext.User.Identity as ClaimsIdentity;
if (identity != null)
{
IEnumerable<Claim> claims = identity.Claims;
// or
identity.FindFirst("ClaimName").Value;
}
Если вы хотите, вы можете написать методы расширения для интерфейса IPrincipal и получить утверждения, используя приведенный выше код, а затем получить их, используя (например)
HttpContext.User.Identity.MethodName();
Для полноты ответа. Чтобы расшифровать токен JWT, давайте напишем метод для проверки токена и извлечения информации.
public static ClaimsPrincipal ValidateToken(string jwtToken)
{
IdentityModelEventSource.ShowPII = true;
SecurityToken validatedToken;
TokenValidationParameters validationParameters = new TokenValidationParameters();
validationParameters.ValidateLifetime = true;
validationParameters.ValidAudience = _audience.ToLower();
validationParameters.ValidIssuer = _issuer.ToLower();
validationParameters.IssuerSigningKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(_appSettings.Secret));
ClaimsPrincipal principal = new JwtSecurityTokenHandler().ValidateToken(jwtToken, validationParameters, out validatedToken);
return principal;
}
Теперь мы можем проверить и извлечь утверждения, используя:
ValidateToken(tokenString)?.FindFirst("ClaimName")?.Value
Обратите внимание, что метод ValidateToken вернет значение null, если проверка не пройдена.
@sameernainawat Похоже, это даже не Java, а код Kotlin.
@sameernainawat as в HttpContext.User.Identity as ClaimsIdentity не является допустимым ключевым словом в Java. Если вы используете что-то другое, кроме простой Java, укажите это в своем вопросе.
Вот как я читаю Claim from Token
private Claims getAllClaimsFromToken(String token) {
Claims claims;
try {
claims = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token)
.getBody();
} catch (Exception e) {
LOGGER.error("Could not get all claims Token from passed token");
claims = null;
}
return claims;
}
Я использую это для JWT
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.0</version>
</dependency>
Редактировать 1:
Добавление фильтра для получения токена из запроса и проверки
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.filter.OncePerRequestFilter;
public class TokenAuthenticationFilter extends OncePerRequestFilter {
protected final Log logger = LogFactory.getLog(getClass());
private TokenHelper tokenHelper;
private UserDetailsService userDetailsService;
public TokenAuthenticationFilter(TokenHelper tokenHelper, UserDetailsService userDetailsService) {
this.tokenHelper = tokenHelper;
this.userDetailsService = userDetailsService;
}
@Override
public void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain chain
) throws IOException, ServletException {
String username;
String authToken = tokenHelper.getToken(request);
logger.info("AuthToken: "+authToken);
if (authToken != null) {
// get username from token
username = tokenHelper.getUsernameFromToken(authToken);
logger.info("UserName: "+username);
if (username != null) {
// get user
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (tokenHelper.validateToken(authToken, userDetails)) {
// create authentication
TokenBasedAuthentication authentication = new TokenBasedAuthentication(userDetails);
authentication.setToken(authToken);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}else{
logger.error("Something is wrong with Token.");
}
}
chain.doFilter(request, response);
}
}
как я получу токен при попадании в API...?
Если вы видите ссылку, которую я добавил. Существует класс TokenAuthenticationFilter, в котором я получаю токен при попадании в API. Вы можете сделать что-то подобное
Я видел ваш код, но не получил ответа на свой вопрос о том, что когда мы нажимаем на API, то на стороне контроллера мы получаем только принципала, детали, учетные данные, полномочия, а в вашем коде мы генерируем токен, поэтому я не не нахожу это связанным с моим вопросом.
Было бы рекомендовано обратиться к блогу, указанному ниже. Он объяснил, как токен JWT работает при весенней загрузке.
https://auth0.com/blog/implementing-jwt-authentication-on-spring-boot/
Используя Spring Security 5, вы можете использовать @AuthenticationPrincipal org.springframework.security.oauth2.jwt.Jwt token в качестве параметра в методе вашего контроллера. А затем позвоните token.getClaims()
Оно работает ! но в интеграционных тестах, как вы издеваетесь над токеном?
есть ли ссылка на предоставленный вами ответ. Я не могу получить HttpContext.User.Identity