package org.pac4j.jwt.profile; import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.PlainJWT; import org.pac4j.core.profile.CommonProfile; import org.pac4j.core.util.CommonHelper; import org.pac4j.core.profile.jwt.JwtClaims; import org.pac4j.jwt.config.encryption.EncryptionConfiguration; import org.pac4j.jwt.config.signature.SignatureConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; /** * Generates a JWT token from a user profile. * * @author Jerome Leleu * @since 1.8.0 */ public class JwtGenerator<U extends CommonProfile> { public static final String INTERNAL_ROLES = "$int_roles"; public static final String INTERNAL_PERMISSIONS = "$int_perms"; protected final Logger logger = LoggerFactory.getLogger(getClass()); private SignatureConfiguration signatureConfiguration; private EncryptionConfiguration encryptionConfiguration; public JwtGenerator() {} public JwtGenerator(final SignatureConfiguration signatureConfiguration) { this.signatureConfiguration = signatureConfiguration; } public JwtGenerator(final SignatureConfiguration signatureConfiguration, final EncryptionConfiguration encryptionConfiguration) { this.signatureConfiguration = signatureConfiguration; this.encryptionConfiguration = encryptionConfiguration; } /** * Generate a JWT from a map of claims. * * @param claims the map of claims * @return the created JWT */ public String generate(final Map<String, Object> claims) { // claims builder final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder(); // add claims for (final Map.Entry<String, Object> entry : claims.entrySet()) { builder.claim(entry.getKey(), entry.getValue()); } return internalGenerate(builder.build()); } /** * Generate a JWT from a user profile. * * @param profile the given user profile * @return the created JWT */ public String generate(final U profile) { verifyProfile(profile); return internalGenerate(buildJwtClaimsSet(profile)); } /** * Generate a JWT from a claims set. * * @param claimsSet the claims set * @return the JWT */ protected String internalGenerate(final JWTClaimsSet claimsSet) { JWT jwt; // signature? if (signatureConfiguration == null) { jwt = new PlainJWT(claimsSet); } else { jwt = signatureConfiguration.sign(claimsSet); } // encryption? if (encryptionConfiguration != null) { return encryptionConfiguration.encrypt(jwt); } else { return jwt.serialize(); } } protected void verifyProfile(final U profile) { CommonHelper.assertNotNull("profile", profile); CommonHelper.assertNull("profile.sub", profile.getAttribute(JwtClaims.SUBJECT)); CommonHelper.assertNull(INTERNAL_ROLES, profile.getAttribute(INTERNAL_ROLES)); CommonHelper.assertNull(INTERNAL_PERMISSIONS, profile.getAttribute(INTERNAL_PERMISSIONS)); } protected JWTClaimsSet buildJwtClaimsSet(final U profile) { // claims builder with subject and issue time final JWTClaimsSet.Builder builder = new JWTClaimsSet.Builder() .subject(profile.getTypedId()); // add attributes final Map<String, Object> attributes = profile.getAttributes(); for (final Map.Entry<String, Object> entry : attributes.entrySet()) { builder.claim(entry.getKey(), entry.getValue()); } builder.claim(INTERNAL_ROLES, profile.getRoles()); builder.claim(INTERNAL_PERMISSIONS, profile.getPermissions()); // claims return builder.build(); } public SignatureConfiguration getSignatureConfiguration() { return signatureConfiguration; } public void setSignatureConfiguration(final SignatureConfiguration signatureConfiguration) { this.signatureConfiguration = signatureConfiguration; } public EncryptionConfiguration getEncryptionConfiguration() { return encryptionConfiguration; } public void setEncryptionConfiguration(final EncryptionConfiguration encryptionConfiguration) { this.encryptionConfiguration = encryptionConfiguration; } @Override public String toString() { return CommonHelper.toString(this.getClass(), "signatureConfiguration", signatureConfiguration, "encryptionConfiguration", encryptionConfiguration); } }