package com.pollex.pam.security.jwt;
|
|
import io.jsonwebtoken.*;
|
import io.jsonwebtoken.io.Decoders;
|
import io.jsonwebtoken.security.Keys;
|
import java.nio.charset.StandardCharsets;
|
import java.security.Key;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.userdetails.User;
|
import org.springframework.stereotype.Component;
|
import org.springframework.util.ObjectUtils;
|
|
import com.pollex.pam.business.domain.TokenBlackList;
|
import com.pollex.pam.business.repository.TokenBlackListRepository;
|
|
import tech.jhipster.config.JHipsterProperties;
|
|
@Component
|
public class TokenProvider {
|
|
private final Logger log = LoggerFactory.getLogger(TokenProvider.class);
|
|
private static final String AUTHORITIES_KEY = "auth";
|
private static final String AUTHORITIES_DETAILS = "details";
|
|
private final Key key;
|
|
private final JwtParser jwtParser;
|
|
private final long tokenValidityInMilliseconds;
|
|
private final long tokenValidityInMillisecondsForRememberMe;
|
|
@Autowired
|
TokenBlackListRepository tokenBlackListRepository;
|
|
public TokenProvider(JHipsterProperties jHipsterProperties) {
|
byte[] keyBytes;
|
String secret = jHipsterProperties.getSecurity().getAuthentication().getJwt().getBase64Secret();
|
if (!ObjectUtils.isEmpty(secret)) {
|
log.debug("Using a Base64-encoded JWT secret key");
|
keyBytes = Decoders.BASE64.decode(secret);
|
} else {
|
log.warn(
|
"Warning: the JWT key used is not Base64-encoded. " +
|
"We recommend using the `jhipster.security.authentication.jwt.base64-secret` key for optimum security."
|
);
|
secret = jHipsterProperties.getSecurity().getAuthentication().getJwt().getSecret();
|
keyBytes = secret.getBytes(StandardCharsets.UTF_8);
|
}
|
key = Keys.hmacShaKeyFor(keyBytes);
|
jwtParser = Jwts.parserBuilder().setSigningKey(key).build();
|
this.tokenValidityInMilliseconds = 1000 * jHipsterProperties.getSecurity().getAuthentication().getJwt().getTokenValidityInSeconds();
|
this.tokenValidityInMillisecondsForRememberMe =
|
1000 * jHipsterProperties.getSecurity().getAuthentication().getJwt().getTokenValidityInSecondsForRememberMe();
|
}
|
|
public String createToken(Authentication authentication, boolean rememberMe) {
|
String authorities = authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.joining(","));
|
|
long now = (new Date()).getTime();
|
Date validity;
|
if (rememberMe) {
|
validity = new Date(now + this.tokenValidityInMillisecondsForRememberMe);
|
} else {
|
validity = new Date(now + this.tokenValidityInMilliseconds);
|
}
|
|
return Jwts
|
.builder()
|
.setSubject(authentication.getName())
|
.claim(AUTHORITIES_KEY, authorities)
|
.claim(AUTHORITIES_DETAILS, authentication.getDetails())
|
.signWith(key, SignatureAlgorithm.HS512)
|
.setExpiration(validity)
|
.compact();
|
}
|
|
public Authentication getAuthentication(String token) {
|
Claims claims = jwtParser.parseClaimsJws(token).getBody();
|
|
Collection<? extends GrantedAuthority> authorities = Arrays
|
.stream(claims.get(AUTHORITIES_KEY).toString().split(","))
|
.filter(auth -> !auth.trim().isEmpty())
|
.map(SimpleGrantedAuthority::new)
|
.collect(Collectors.toList());
|
|
User principal = new User(claims.getSubject(), "", authorities);
|
UsernamePasswordAuthenticationToken authInfo = new UsernamePasswordAuthenticationToken(principal, token, authorities);
|
authInfo.setDetails(claims.get(AUTHORITIES_DETAILS));
|
|
return authInfo;
|
}
|
|
public boolean validateToken(String authToken) {
|
try {
|
jwtParser.parseClaimsJws(authToken);
|
return true;
|
} catch (JwtException | IllegalArgumentException e) {
|
log.info("Invalid JWT token.");
|
log.trace("Invalid JWT token trace.", e);
|
}
|
return false;
|
}
|
|
public boolean isBlackListToken(String jwt) {
|
Optional<TokenBlackList> tokenBlack = tokenBlackListRepository.findById(jwt);
|
return tokenBlack.isPresent();
|
}
|
}
|