Как получить значение требований от аутентификации токена JWT

Я установил претензии в токене 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» от аутентификации или любым другим способом получить значение утверждения из токена.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
0
31 781
4

Ответы 4

Это должно помочь.

Вы должны иметь возможность получать такие утверждения в своем контроллере.

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, если проверка не пройдена.

есть ли ссылка на предоставленный вами ответ. Я не могу получить HttpContext.User.Identity

sameer nainawat 24.01.2019 07:08

@sameernainawat Похоже, это даже не Java, а код Kotlin.

howlger 24.01.2019 11:04

@sameernainawat as в HttpContext.User.Identity as ClaimsIdentity не является допустимым ключевым словом в Java. Если вы используете что-то другое, кроме простой Java, укажите это в своем вопросе.

howlger 24.01.2019 13:09

Вот как я читаю 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...?

sameer nainawat 24.01.2019 07:04

Если вы видите ссылку, которую я добавил. Существует класс TokenAuthenticationFilter, в котором я получаю токен при попадании в API. Вы можете сделать что-то подобное

MyTwoCents 24.01.2019 07:13

Я видел ваш код, но не получил ответа на свой вопрос о том, что когда мы нажимаем на API, то на стороне контроллера мы получаем только принципала, детали, учетные данные, полномочия, а в вашем коде мы генерируем токен, поэтому я не не нахожу это связанным с моим вопросом.

sameer nainawat 24.01.2019 12:42

Было бы рекомендовано обратиться к блогу, указанному ниже. Он объяснил, как токен JWT работает при весенней загрузке.

https://auth0.com/blog/implementing-jwt-authentication-on-spring-boot/

Используя Spring Security 5, вы можете использовать @AuthenticationPrincipal org.springframework.security.oauth2.jwt.Jwt token в качестве параметра в методе вашего контроллера. А затем позвоните token.getClaims()

Оно работает ! но в интеграционных тестах, как вы издеваетесь над токеном?

slim 28.12.2021 17:51

Другие вопросы по теме