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

de.yourinspiration.spring.jwt.JwtServiceImpl Maven / Gradle / Ivy

The newest version!
package de.yourinspiration.spring.jwt;

import java.util.Date;
import java.util.Optional;

import javax.servlet.http.HttpServletRequest;

import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSSigner;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;

/**
 * Simple implementation for {@link JwtService}.
 * 
 * @author Marcel Härle - [email protected]
 *
 */
public class JwtServiceImpl implements JwtService {

    private final String secret;
    private final UserService userService;
    private final String issuer;
    private final long expirationTime;
    private final String headerField;
    private final String attribute;
    private final JWSHeader header = new JWSHeader(JWSAlgorithm.HS256);
    private final JWSVerifier verifier;
    private final JWSSigner signer;

    protected JwtServiceImpl(final String secret, final String headerField, final UserService userService,
            final String issuer, final long expirationTime, final String attribute) {
        this.secret = secret;
        this.headerField = headerField;
        this.userService = userService;
        this.issuer = issuer;
        this.expirationTime = expirationTime;
        this.attribute = attribute;
        this.signer = new MACSigner(secret.getBytes());
        this.verifier = new MACVerifier(secret.getBytes());
    }

    @Override
    public Token createTokenFromSubject(final String subject) {
        if (subject == null || subject.isEmpty()) {
            throw new IllegalArgumentException("subject must not be null or empty");
        }
        final JWTClaimsSet claimsSet = getClaimsSetFromSubject(subject);
        final SignedJWT signedJWT = getSignedJWT(claimsSet);
        return getTokenFromSignedJWT(claimsSet, signedJWT);
    }

    @Override
    public Optional getJwtSubject(final HttpServletRequest request) {
        final String headerToken = request.getHeader(this.headerField);
        return getJwtSubjectFromToken(headerToken);
    }

    @Override
    public boolean authenticate(HttpServletRequest request, String[] roles) {
        String headerToken = request.getHeader(this.headerField);
        if (isValidToken(headerToken)) {
            final String[] userRoles = userService.getRolesForSubject(getJwtSubject(request).get());
            for (String role : roles) {
                for (String userRole : userRoles) {
                    if (role.equals(userRole)) {
                        return true;
                    }
                }
            }
            return false;
        } else {
            return false;
        }
    }

    @Override
    public String getRequestAttribute() {
        return attribute;
    }

    private Token getTokenFromSignedJWT(final JWTClaimsSet claimsSet, final SignedJWT signedJWT) {
        final Token token = new Token();
        token.setToken(signedJWT.serialize());
        token.setExpirationTime(claimsSet.getExpirationTimeClaim());
        token.setIssuedAt(claimsSet.getIssuedAtClaim());
        token.setIssuer(claimsSet.getIssuerClaim());
        return token;
    }

    private JWTClaimsSet getClaimsSetFromSubject(final String subject) {
        JWTClaimsSet claimsSet = new JWTClaimsSet();
        claimsSet.setSubjectClaim(subject);
        claimsSet.setIssuedAtClaim(new Date().getTime());
        claimsSet.setExpirationTimeClaim(calculateExpirationTime());
        claimsSet.setIssuerClaim(this.issuer);
        return claimsSet;
    }

    private long calculateExpirationTime() {
        return new Date().getTime() + this.expirationTime;
    }

    private boolean isValidToken(String token) {
        if (token == null) {
            return false;
        }
        if (getJwtSubjectFromToken(token).isPresent()) {
            return true;
        } else {
            return false;
        }
    }

    private Optional getJwtSubjectFromToken(final String token) {
        if (token == null || token.isEmpty()) {
            return Optional.empty();
        }
        try {
            final SignedJWT signedJWT = SignedJWT.parse(token);
            if (signedJWT.verify(verifier)) {
                return Optional.ofNullable(signedJWT.getJWTClaimsSet().getSubjectClaim());
            } else {
                return Optional.empty();
            }
        } catch (Exception e) {
            return Optional.empty();
        }
    }

    private SignedJWT getSignedJWT(final JWTClaimsSet claimsSet) {
        final SignedJWT signedJWT = new SignedJWT(this.header, claimsSet);
        try {
            signedJWT.sign(this.signer);
        } catch (JOSEException e) {
            throw new JwtServiceException("error signing the token", e);
        }
        return signedJWT;
    }

    protected String getHeaderField() {
        return headerField;
    }

    protected String getSecret() {
        return secret;
    }

    protected UserService getUserService() {
        return userService;
    }

    protected String getIssuer() {
        return issuer;
    }

    protected long getExpirationTime() {
        return expirationTime;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy