All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.rocketbase.commons.security.JwtTokenService Maven / Gradle / Ivy

There is a newer version: 4.4.1
Show newest version
package io.rocketbase.commons.security;

import io.jsonwebtoken.*;
import io.rocketbase.commons.config.JwtProperties;
import io.rocketbase.commons.dto.authentication.JwtTokenBundle;
import io.rocketbase.commons.model.AppUser;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
public class JwtTokenService implements Serializable {

    public static final String REFRESH_TOKEN = "REFRESH_TOKEN";

    final JwtProperties jwtProperties;
    final CustomAuthoritiesProvider customAuthoritiesProvider;

    public String getUsernameFromToken(String token) {
        return getClaimFromToken(token, Claims::getSubject);
    }

    public Collection getAuthoritiesFromToken(String token) {
        Claims claims = getAllClaimsFromToken(token);
        List roles = (List) claims.getOrDefault("scopes", Collections.emptyList());
        List result = new ArrayList<>();
        for (Object r : roles) {
            result.add(new SimpleGrantedAuthority(String.valueOf(r)));
        }
        return result;
    }

    public LocalDateTime getIssuedAtDateFromToken(String token) {
        Date issuedAt = getClaimFromToken(token, Claims::getIssuedAt);
        return LocalDateTime.ofInstant(issuedAt.toInstant(), ZoneOffset.UTC);
    }

    public LocalDateTime getExpirationDateFromToken(String token) {
        Date expiration = getClaimFromToken(token, Claims::getExpiration);
        return LocalDateTime.ofInstant(expiration.toInstant(), ZoneOffset.UTC);
    }

    public  T getClaimFromToken(String token, Function claimsResolver) {
        final Claims claims = getAllClaimsFromToken(token);
        return claimsResolver.apply(claims);
    }

    private Claims getAllClaimsFromToken(String token) {
        return Jwts.parser()
                .setSigningKey(jwtProperties.getSecret())
                .parseClaimsJws(token)
                .getBody();
    }

    public JwtTokenBundle generateTokenBundle(AppUser appUser) {
        return generateTokenBundle(appUser.getUsername(), appUser.getAuthorities());
    }

    public JwtTokenBundle generateTokenBundle(String username, Collection authorities) {
        LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
        return new JwtTokenBundle(generateAccessToken(now, username, authorities),
                prepareBuilder(now, jwtProperties.getRefreshTokenExpiration(), username)
                        .claim("scopes", Arrays.asList(REFRESH_TOKEN))
                        .compact());
    }

    public String generateAccessToken(String username, Collection authorities) {
        return generateAccessToken(LocalDateTime.now(ZoneOffset.UTC), username, authorities);
    }

    protected String generateAccessToken(LocalDateTime ldt, String username, Collection authorities) {
        List scopes = new ArrayList<>();
        scopes.addAll(authorities);
        scopes.addAll(customAuthoritiesProvider.getExtraTokenAuthorities(username));

        return prepareBuilder(ldt, jwtProperties.getAccessTokenExpiration(), username)
                .claim("scopes", scopes.stream().map(a -> a.getAuthority()).collect(Collectors.toSet()))
                .compact();
    }

    private JwtBuilder prepareBuilder(LocalDateTime ldt, long expirationMinutes, String username) {
        return Jwts.builder()
                .setIssuedAt(convert(ldt))
                .setExpiration(convert(ldt.plusMinutes(expirationMinutes)))
                .signWith(SignatureAlgorithm.HS512, jwtProperties.getSecret())
                .setSubject(username);
    }

    private Date convert(LocalDateTime ldt) {
        return Date.from(ldt.atZone(ZoneOffset.UTC)
                .toInstant());
    }

    public Boolean validateToken(String token, AppUser user) {
        try {
            getAllClaimsFromToken(token);
        } catch (JwtException e) {
            // should show catch expiration etc. exceptions
            if (log.isTraceEnabled()) {
                log.trace("token is invalid", e);
            }
            return false;
        }
        if (!getUsernameFromToken(token).equals(user.getUsername())) {
            // username not fitting
            if (log.isTraceEnabled()) {
                log.trace("token username differs");
            }
            return false;
        }
        if (user.getLastTokenInvalidation() == null) {
            return true;
        } else {
            // check if token creation is newer then last token invalidation
            boolean validIssued = user.getLastTokenInvalidation().isBefore(getIssuedAtDateFromToken(token));
            if (log.isTraceEnabled() && !validIssued) {
                log.trace("token is issued {} before lastTokenInvalidation {}", getIssuedAtDateFromToken(token), user.getLastTokenInvalidation());
            }
            return validIssued;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy