package org.ohdsi.webapi.shiro;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwsHeader;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MissingClaimException;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.SignatureException;
import io.jsonwebtoken.SigningKeyResolverAdapter;
import io.jsonwebtoken.impl.crypto.MacProvider;
import java.security.Key;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.web.util.WebUtils;
/**
*
* @author gennadiy.anisimov
*/
public class TokenManager {
private static final String AUTHORIZATION_HEADER = "Authorization";
private static final Map<String, Key> userToKeyMap = new HashMap<>();
public static String createJsonWebToken(String subject, Date expiration, Collection<String> permissions) {
Key key = MacProvider.generateKey();
userToKeyMap.put(subject, key);
String permissionsString = StringUtils.join(permissions, "|");
Map<String, Object> claims = new HashMap<>();
claims.put("permissions", permissionsString);
return Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setExpiration(expiration)
.signWith(SignatureAlgorithm.HS512, key)
.compact();
}
public static String getSubject(String jwt) throws JwtException {
return getBody(jwt).getSubject();
}
private static Claims getBody(String jwt) {
return Jwts.parser()
.setSigningKeyResolver(new SigningKeyResolverAdapter() {
@Override
public Key resolveSigningKey(JwsHeader header, Claims claims) {
String subject = claims.getSubject();
if (subject == null || subject.isEmpty())
throw new MissingClaimException(header, claims, "Subject is not provided in JWT.");
if (!userToKeyMap.containsKey(subject))
throw new SignatureException("Signing key is not reqistred for the subject.");
return userToKeyMap.get(subject);
}})
.parseClaimsJws(jwt)
.getBody();
}
public static Boolean invalidate(String jwt) {
if (jwt == null)
return false;
String subject;
try {
subject = getSubject(jwt);
}
catch(JwtException e) {
return false;
}
if (!userToKeyMap.containsKey(subject))
return false;
userToKeyMap.remove(subject);
return true;
}
public static String extractToken(ServletRequest request) {
HttpServletRequest httpRequest = WebUtils.toHttp(request);
String header = httpRequest.getHeader(AUTHORIZATION_HEADER);
if (header == null || header.isEmpty())
return null;
if (!header.toLowerCase(Locale.ENGLISH).startsWith("bearer"))
return null;
String[] headerParts = header.split(" ");
if (headerParts.length != 2)
return null;
String jwt = headerParts[1];
return jwt;
}
}