Безопасность Spring: прочитайте подробности JWT - PullRequest
0 голосов
/ 03 октября 2018

Я получаю jwt после вызова /login:

ResponseEntity<Void> responseEntity = restTemplate
  .postForEntity(url, entity, Void.class); 

String bearer = responseEntity
  .getHeaders()
  .get("Authorization")
  .stream().findFirst().get();

После этого я получаю токен jwt на заголовок Authorization, например:

"Знаменосец eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1Mzg1NjExNDgsInN1YiI6ImFkbWluIiwiZXhwIjoxNTM5NDI1MTQ4fQ.mr4MdNzNC8h1uq-OF9DeEBGS8AFgkN6ysooptNrvJeyyn6L6TLV1W4hv6osMggNpo_Ee6RqBhwuJu1beA8OFoA"

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

1013 * есть ли библиотека справиться с этим?

Предоставляет ли Spring какой-нибудь помощник для его лечения?

Очевидно, у меня есть секретный ключ.

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

вот пример кода из моего проекта;

static final String CLAIM_KEY_USERNAME = "sub";
static final String CLAIM_KEY_AUDIENCE = "audience";
static final String CLAIM_KEY_CREATED = "created";

private static final String AUDIENCE_UNKNOWN = "unknown";
private static final String AUDIENCE_WEB = "web";
private static final String AUDIENCE_MOBILE = "mobile";
private static final String AUDIENCE_TABLET = "tablet";

@Value("${jwt.secret}")
private String secret;

@Value("${jwt.expiration}")
private Long expiration;

public String getUsernameFromToken(String token) {
    final Claims claims = getClaimsFromToken(token);
    return claims != null ? claims.getSubject() : null;
}

public Date getCreatedDateFromToken(String token) {
    final Claims claims = getClaimsFromToken(token);
    return claims != null ? new Date((Long) claims.get(CLAIM_KEY_CREATED)) : null;
}

public Date getExpirationDateFromToken(String token) {
    final Claims claims = getClaimsFromToken(token);
    return claims != null ? claims.getExpiration() : null;
}

public String getAudienceFromToken(String token) {
    final Claims claims = getClaimsFromToken(token);
    return claims != null ? (String) claims.get(CLAIM_KEY_AUDIENCE) : null;
}

private Claims getClaimsFromToken(String token) {
    return StringUtils.hasText(token) ? Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody() : null;
}

private Date generateExpirationDate() {
    return new Date(System.currentTimeMillis() + expiration * 1000);
}

private Boolean isTokenExpired(String token) {
    final Date expirationDate = getExpirationDateFromToken(token);
    return expirationDate.before(new Date());
}

private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) {
    return (lastPasswordReset != null && created.before(lastPasswordReset));
}

private String generateAudience(Device device) {
    String audience = AUDIENCE_UNKNOWN;
    if (device.isNormal()) {
        audience = AUDIENCE_WEB;
    } else if (device.isTablet()) {
        audience = AUDIENCE_TABLET;
    } else if (device.isMobile()) {
        audience = AUDIENCE_MOBILE;
    }
    return audience;
}

private Boolean ignoreTokenExpiration(String token) {
    String audience = getAudienceFromToken(token);
    return (AUDIENCE_TABLET.equals(audience) || AUDIENCE_MOBILE.equals(audience));
}

 public String generateToken(UserDetails userDetails, Device device) {
    Map<String, Object> claims = new HashMap<>();
    claims.put(CLAIM_KEY_USERNAME, userDetails.getUsername());
    claims.put(CLAIM_KEY_AUDIENCE, generateAudience(device));
    claims.put(CLAIM_KEY_CREATED, new Date());
    return generateToken(claims);
}

String generateToken(Map<String, Object> claims) {
    return Jwts.builder().setClaims(claims).setExpiration(generateExpirationDate()).signWith(SignatureAlgorithm.HS512, secret).compact();
}

public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) {
    final Date created = getCreatedDateFromToken(token);
    return !isCreatedBeforeLastPasswordReset(created, lastPasswordReset) && (!isTokenExpired(token) || ignoreTokenExpiration(token));
}

public String refreshToken(String token) {
    String refreshedToken;
    try {
        final Claims claims = getClaimsFromToken(token);
        claims.put(CLAIM_KEY_CREATED, new Date());
        refreshedToken = generateToken(claims);
    } catch (Exception e) {
        refreshedToken = null;
    }
    return refreshedToken;
}

public Boolean validateToken(String token, UserDetails userDetails) {
    JwtUser user = (JwtUser) userDetails;
    final String username = getUsernameFromToken(token);
    final Date created = getCreatedDateFromToken(token);
    return (username.equals(user.getUsername()) && !isTokenExpired(token) && !isCreatedBeforeLastPasswordReset(created, user.getLastPasswordResetDate()));
}
0 голосов
/ 03 октября 2018

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

Например, я использую jsonwebtoken для разбора токена.Примерно так:

public Claims getClaimsFromToken(String token) throws Exception {
        Claims claims;

        claims = Jwts.parser()
                .setSigningKey(SECRET)
                .parseClaimsJws(token)
                .getBody(); 

        return claims;
    }

Если вы хотите получить значение определенного ключа в ваших утверждениях, вы можете сделать это следующим образом;

public Object getClaimsValueFromToken(String token, String key) throws Exception {
        Claims claims = getClaimsFromToken(token);
        Object value = claims.get(key);
        return value;
    }

В идеале вы можете создать свой собственный custom util, используя jwt library, который будет использоваться для анализа токена.


Не забудьтетакже добавить библиотеку как зависимость maven;

<dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.6.0</version>
        </dependency>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...