SecurityServiceImpl.java
package no.ntnu.idatt2105.l4.demo.service;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Service;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* This is a simple implementation for dealing with JWTs.
*
* All it really does, is show an implementation for how to create a JWT,
* and how to get a claim (the subject), from an already exists JWT.
*
* This implementation should be more or less directly applicable for
* your needs (slight expansion might be needed).
*/
@Service
public class SecurityServiceImpl implements SecurityService {
public static final String secretKey= "4C8kum4LxyKWYLM78sKdXrzbBjDCFyfX";
private static List<String> tokens = new ArrayList<String>(); // JWTs are just strings, in the end
/**
* Creates a JWT token with one claim: the subject. The signs it and returns it.
*
* @param subject Basically, whatever you decide to use as user id.
* @param ttlMillis how long the JWT will last before it needs to be renewed (or becomes invalid).
* @return a signed JWT.
*/
@Override
public String createToken(String subject, long ttlMillis) {
if (ttlMillis <= 0) {
throw new RuntimeException("Expiry time must be greater than Zero :["+ttlMillis+"] ");
}
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
// The JWT signature algorithm we will be using to sign the token
long nowMillis = System.currentTimeMillis();
byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(secretKey);
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
JwtBuilder builder = Jwts.builder()
.setSubject(subject)
.signWith(signatureAlgorithm, signingKey);
// builder.setExpiration(new Date(nowMillis + ttlMillis));
builder.setExpiration(new Date(nowMillis + (1000*60*15)));
// At this point, we can add the token to a List (either in this class, or in a singleton)
// which we can then check against when the aspect is run (see TokenRequiredAspect).
String token = builder.compact();
tokens.add(token);
return token;
}
/**
* The subject in JWT parlance is, practically speaking, the same thing as the user id.
*
* @param token the JWT token
* @return the user ID (or whatever one has decided to refer to as "subject")
*/
@Override
public String getSubject(String token) {
Claims claims = Jwts.parser()
.setSigningKey(DatatypeConverter.parseBase64Binary(secretKey))
.parseClaimsJws(token).getBody();
return claims.getSubject();
}
/**
* We simply put all of our tokens in a list, and check to see if the token is in it.
*
* @param token the JWT
* @return true, if the token is in the list of valid tokens, false otherwise.
*/
@Override
public boolean validToken(String token) {
return this.tokens.contains(token);
}
}