Skip to content

Commit

Permalink
Support mp.jwt.verify.publickey.algorithm.
Browse files Browse the repository at this point in the history
  • Loading branch information
radcortez committed May 25, 2020
1 parent 5a160f9 commit 30426f8
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import javax.inject.Inject;

import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.eclipse.microprofile.jwt.config.Names;
import org.jboss.logging.Logger;

import io.smallrye.jwt.KeyFormat;
Expand Down Expand Up @@ -98,6 +97,7 @@ private static JWTAuthContextInfoProvider create(String publicKey, String public
JWTAuthContextInfoProvider provider = new JWTAuthContextInfoProvider();
provider.mpJwtPublicKey = Optional.of(publicKey);
provider.mpJwtLocation = Optional.of(publicKeyLocation);
provider.mpJwtPublicKeyAlgorithm = Optional.of(SignatureAlgorithm.RS256);
provider.mpJwtDecryptKeyLocation = Optional.of(decryptKeyLocation);
provider.mpJwtIssuer = issuer;
provider.mpJwtRequireIss = Optional.of(Boolean.TRUE);
Expand All @@ -119,9 +119,9 @@ private static JWTAuthContextInfoProvider create(String publicKey, String public
provider.maxTimeToLiveSecs = Optional.empty();
provider.jwksRefreshInterval = Optional.empty();
provider.forcedJwksRefreshInterval = 30;
provider.signatureAlgorithm = Optional.of(SignatureAlgorithm.RS256);
provider.signatureAlgorithm = provider.mpJwtPublicKeyAlgorithm;
provider.keyFormat = KeyFormat.ANY;
provider.expectedAudience = Optional.empty();
provider.expectedAudience = provider.mpJwtVerifyAudiences;
provider.groupsSeparator = DEFAULT_GROUPS_SEPARATOR;
provider.requiredClaims = Optional.empty();

Expand All @@ -130,59 +130,66 @@ private static JWTAuthContextInfoProvider create(String publicKey, String public
// The MP-JWT spec defined configuration properties

/**
* @since 1.1
* @apiNote MP JWT 1.1
*/
@Inject
@ConfigProperty(name = "mp.jwt.verify.publickey", defaultValue = NONE)
private Optional<String> mpJwtPublicKey;

/**
* @since 1.1
* @apiNote MP JWT 1.1
*/
@Inject
@ConfigProperty(name = "mp.jwt.verify.publickey.location", defaultValue = NONE)
private Optional<String> mpJwtLocation;

/**
* @since 1.1
* @apiNote MP JWT 1.2
*/
@Inject
@ConfigProperty(name = "mp.jwt.verify.publickey.algorithm")
private Optional<SignatureAlgorithm> mpJwtPublicKeyAlgorithm;

/**
* @apiNote MP JWT 1.1
*/
@Inject
@ConfigProperty(name = "mp.jwt.decrypt.key.location", defaultValue = NONE)
private Optional<String> mpJwtDecryptKeyLocation;

/**
* @since 1.1
* @apiNote MP JWT 1.1
*/
@Inject
@ConfigProperty(name = "mp.jwt.verify.issuer", defaultValue = NONE)
private String mpJwtIssuer;

/**
* Not part of the 1.1 release, but talked about.
* @apiNote MP JWT 1.1
*/
@Inject
@ConfigProperty(name = "mp.jwt.verify.requireiss", defaultValue = "true")
private Optional<Boolean> mpJwtRequireIss;

/**
* @since 1.2
* @apiNote MP JWT 1.2
*/
@Inject
@ConfigProperty(name = Names.TOKEN_HEADER)
@ConfigProperty(name = "mp.jwt.token.header")
private Optional<String> mpJwtTokenHeader;

/**
* @since 1.2
* @apiNote MP JWT 1.2
*/
@Inject
@ConfigProperty(name = Names.TOKEN_COOKIE)
@ConfigProperty(name = "mp.jwt.token.cookie")
private Optional<String> mpJwtTokenCookie;

/**
* @since 1.2
* @apiNote MP JWT 1.2
*/
@Inject
@ConfigProperty(name = Names.AUDIENCES)
@ConfigProperty(name = "mp.jwt.verify.audiences")
Optional<Set<String>> mpJwtVerifyAudiences;

// SmallRye JWT specific properties
Expand All @@ -193,6 +200,7 @@ private static JWTAuthContextInfoProvider create(String publicKey, String public
*/
@Inject
@ConfigProperty(name = "smallrye.jwt.token.header")
@Deprecated
private Optional<String> tokenHeader;

/**
Expand All @@ -202,6 +210,7 @@ private static JWTAuthContextInfoProvider create(String publicKey, String public
*/
@Inject
@ConfigProperty(name = "smallrye.jwt.token.cookie")
@Deprecated
private Optional<String> tokenCookie;

/**
Expand Down Expand Up @@ -330,9 +339,12 @@ private static JWTAuthContextInfoProvider create(String publicKey, String public

/**
* Supported JSON Web Algorithm asymmetric signature algorithm (RS256 or ES256), default is RS256.
*
* @deprecated Use {@link JWTAuthContextInfoProvider#mpJwtPublicKeyAlgorithm}
*/
@Inject
@ConfigProperty(name = "smallrye.jwt.verify.algorithm", defaultValue = "RS256")
@ConfigProperty(name = "smallrye.jwt.verify.algorithm")
@Deprecated
private Optional<SignatureAlgorithm> signatureAlgorithm;

/**
Expand All @@ -354,6 +366,7 @@ private static JWTAuthContextInfoProvider create(String publicKey, String public
*/
@Inject
@ConfigProperty(name = "smallrye.jwt.verify.aud")
@Deprecated
Optional<Set<String>> expectedAudience;

/**
Expand Down Expand Up @@ -402,17 +415,17 @@ Optional<JWTAuthContextInfo> getOptionalContextInfo() {
if (mpJwtTokenHeader.isPresent()) {
contextInfo.setTokenHeader(mpJwtTokenHeader.get());
} else if (tokenHeader.isPresent()) {
ConfigLogging.log.replacedConfig("smallrye.jwt.token.header", "mp.jwt.token.header");
contextInfo.setTokenHeader(tokenHeader.get());
ConfigLogging.log.replacedConfig("smallrye.jwt.token.header", Names.TOKEN_HEADER);
} else {
contextInfo.setTokenHeader(AUTHORIZATION_HEADER);
}

if (mpJwtTokenCookie.isPresent()) {
SmallryeJwtUtils.setContextTokenCookie(contextInfo, mpJwtTokenCookie);
} else if (tokenCookie.isPresent()) {
ConfigLogging.log.replacedConfig("smallrye.jwt.token.cookie", "mp.jwt.token.cookie");
SmallryeJwtUtils.setContextTokenCookie(contextInfo, tokenCookie);
ConfigLogging.log.replacedConfig("smallrye.jwt.token.cookie", Names.TOKEN_COOKIE);
} else {
SmallryeJwtUtils.setContextTokenCookie(contextInfo, Optional.of(BEARER_SCHEME));
}
Expand All @@ -430,16 +443,29 @@ Optional<JWTAuthContextInfo> getOptionalContextInfo() {
contextInfo.setMaxTimeToLiveSecs(maxTimeToLiveSecs.orElse(null));
contextInfo.setJwksRefreshInterval(jwksRefreshInterval.orElse(null));
contextInfo.setForcedJwksRefreshInterval(forcedJwksRefreshInterval);
if (signatureAlgorithm.orElse(null) == SignatureAlgorithm.HS256) {
throw ConfigMessages.msg.hs256NotSupported();
final Optional<SignatureAlgorithm> resolvedAlgorithm;
if (mpJwtPublicKeyAlgorithm.isPresent()) {
resolvedAlgorithm = mpJwtPublicKeyAlgorithm;
} else if (signatureAlgorithm.isPresent()) {
ConfigLogging.log.replacedConfig("smallrye.jwt.verify.algorithm", "mp.jwt.verify.publickey.algorithm");
resolvedAlgorithm = signatureAlgorithm;
} else {
resolvedAlgorithm = Optional.empty();
}
if (resolvedAlgorithm.isPresent()) {
if (resolvedAlgorithm.get() == SignatureAlgorithm.HS256) {
throw ConfigMessages.msg.hs256NotSupported();
}
contextInfo.setSignatureAlgorithm(resolvedAlgorithm.get());
} else {
contextInfo.setSignatureAlgorithm(SignatureAlgorithm.RS256);
}
contextInfo.setSignatureAlgorithm(signatureAlgorithm.orElse(SignatureAlgorithm.RS256));
contextInfo.setKeyFormat(keyFormat);
if (mpJwtVerifyAudiences.isPresent()) {
contextInfo.setExpectedAudience(mpJwtVerifyAudiences.get());
} else if (expectedAudience.isPresent()) {
ConfigLogging.log.replacedConfig("smallrye.jwt.verify.aud", "mp.jwt.verify.audiences");
contextInfo.setExpectedAudience(expectedAudience.get());
ConfigLogging.log.replacedConfig("smallrye.jwt.verify.aud", Names.AUDIENCES);
} else {
contextInfo.setExpectedAudience(null);
}
Expand Down Expand Up @@ -482,6 +508,10 @@ public Optional<String> getMpJwtLocation() {
return mpJwtLocation;
}

public Optional<SignatureAlgorithm> getMpJwtPublicKeyAlgorithm() {
return mpJwtPublicKeyAlgorithm;
}

public Optional<String> getMpJwtDecryptKeyLocation() {
return mpJwtDecryptKeyLocation;
}
Expand Down Expand Up @@ -568,6 +598,7 @@ public Optional<String> getDefaultSubjectClaim() {
return defaultSubClaim;
}

@Deprecated
public Optional<SignatureAlgorithm> getSignatureAlgorithm() {
return signatureAlgorithm;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.junit.Test;

import io.smallrye.config.inject.ConfigExtension;
import io.smallrye.jwt.algorithm.SignatureAlgorithm;
import io.smallrye.jwt.auth.principal.JWTAuthContextInfo;

public class JWTAuthContextInfoProviderTest {
Expand All @@ -36,9 +37,11 @@ public void tearDown() throws Exception {
System.clearProperty("mp.jwt.token.header");
System.clearProperty("mp.jwt.token.cookie");
System.clearProperty("mp.jwt.verify.audiences");
System.clearProperty("mp.jwt.verify.publickey.algorithm");
System.clearProperty("smallrye.jwt.token.header");
System.clearProperty("smallrye.jwt.token.cookie");
System.clearProperty("smallrye.jwt.verify.aud");
System.clearProperty("smallrye.jwt.verify.algorithm");
}

@Test
Expand Down Expand Up @@ -108,4 +111,30 @@ public void mpAudienceConfigPriority() {
assertEquals(1, contextInfo.getExpectedAudience().size());
assertTrue(contextInfo.getExpectedAudience().contains("1234"));
}

@Test
public void algorithmsConfigs() {
System.setProperty("mp.jwt.verify.publickey.algorithm", "ES256");
JWTAuthContextInfo contextInfo = context.get().getOptionalContextInfo().get();
assertEquals(SignatureAlgorithm.ES256, contextInfo.getSignatureAlgorithm());
assertThrows(NoSuchElementException.class,
() -> ConfigProvider.getConfig().getValue("smallrye.jwt.verify.algorithm", String.class));
}

@Test
public void smallryeAlgorithmsConfigs() {
System.setProperty("smallrye.jwt.verify.algorithm", "ES256");
JWTAuthContextInfo contextInfo = context.get().getOptionalContextInfo().get();
assertEquals(SignatureAlgorithm.ES256, contextInfo.getSignatureAlgorithm());
assertThrows(NoSuchElementException.class,
() -> ConfigProvider.getConfig().getValue("mp.jwt.verify.publickey.algorithm", String.class));
}

@Test
public void mpAlgorithmsConfigPriority() {
System.setProperty("mp.jwt.verify.publickey.algorithm", "ES256");
System.setProperty("smallrye.jwt.verify.aud", "RS256");
JWTAuthContextInfo contextInfo = context.get().getOptionalContextInfo().get();
assertEquals(SignatureAlgorithm.ES256, contextInfo.getSignatureAlgorithm());
}
}
6 changes: 3 additions & 3 deletions testsuite/tck/src/test/resources/tck-base-suite.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@
<class name="org.eclipse.microprofile.jwt.tck.config.PublicKeyAsJWKSLocationTest" />
<class name="org.eclipse.microprofile.jwt.tck.config.PublicKeyAsBase64JWKTest" />
<class name="org.eclipse.microprofile.jwt.tck.config.PublicKeyAsFileLocationURLTest" />
<!--<class name="org.eclipse.microprofile.jwt.tck.config.ECPublicKeyAsPEMTest" />-->
<!--<class name="org.eclipse.microprofile.jwt.tck.config.ECPublicKeyAsPEMLocationTest" />-->
<!--<class name="org.eclipse.microprofile.jwt.tck.config.ECPublicKeyAsJWKLocationTest" />-->
<class name="org.eclipse.microprofile.jwt.tck.config.ECPublicKeyAsPEMTest" />
<class name="org.eclipse.microprofile.jwt.tck.config.ECPublicKeyAsPEMLocationTest" />
<class name="org.eclipse.microprofile.jwt.tck.config.ECPublicKeyAsJWKLocationTest" />
<class name="org.eclipse.microprofile.jwt.tck.config.IssNoValidationNoIssTest" />
<class name="org.eclipse.microprofile.jwt.tck.config.IssNoValidationBadIssTest" />
<class name="org.eclipse.microprofile.jwt.tck.config.IssValidationTest" />
Expand Down

0 comments on commit 30426f8

Please sign in to comment.