[java-idp-oidc] branch main updated: JOIDC-144 - Improve token audience handling with JWT authentication
Henri Mikkonen
henri.mikkonen at iki.fi
Fri Apr 14 06:02:00 UTC 2023
This is an automated email from the git hooks/post-receive script.
hjmikkon pushed a commit to branch main
in repository java-idp-oidc.
View the commit online:
http://git.shibboleth.net/view/?p=java-idp-oidc.git;a=commit;h=587c291fc83b3bd98cd7b2697465f1004235d03c
The following commit(s) were added to refs/heads/main by this push:
new 587c291f JOIDC-144 - Improve token audience handling with JWT authentication
587c291f is described below
commit 587c291fc83b3bd98cd7b2697465f1004235d03c
Author: Henri Mikkonen <henri.mikkonen at iki.fi>
AuthorDate: Fri Apr 14 09:01:08 2023 +0300
JOIDC-144 - Improve token audience handling with JWT authentication
https://shibboleth.atlassian.net/browse/JOIDC-144
Now uses the new AuthenticationAudienceClaimsValidator from commons for validating
audience claim in JWT authn. The default configuration accepts the use of
issuer claim (via responder ID lookup), the flow endpoint URL and token endpoint
URL in token, introspection and revocation endpoints.
A custom bean can be wired via idp.oauth2.jwtAuth.audienceValidator -property.
For the default validator, endpoint targets where the token endpoint URL can
be used may be modified via idp.oauth2.jwtAuth.audienceValidator.endpointTargets -property.
Its default value '/profile/oauth2/introspection,/profile/oauth2/revocation' covers the
introspection and revocation endpoints.
---
.../idp/service/relying-party/postconfig.xml | 8 ++++--
.../idp/plugin/oidc/op/conf/oidc.properties | 7 ++++-
.../AbstractOidcClientAuthenticationFlowTest.java | 32 ++++++++++++++++++++--
.../op/profile/flow/IntrospectionFlowTest.java | 1 +
.../oidc/op/profile/flow/RevocationFlowTest.java | 2 +-
5 files changed, 43 insertions(+), 7 deletions(-)
diff --git a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
index 0356dd18..21976c0e 100644
--- a/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
+++ b/idp-oidc-extension-impl/src/main/resources/META-INF/net/shibboleth/idp/service/relying-party/postconfig.xml
@@ -514,8 +514,10 @@
class="net.shibboleth.oidc.security.jwt.claims.impl.ExactMatchClaimsValidator"
p:claimName="sub" p:valueToMatchLookupStrategy-ref="AdaptedRelyingPartyIdLookup" />
- <bean id="AudienceClaimsValidator"
- class="net.shibboleth.oidc.security.jwt.claims.impl.AudienceClaimsValidator">
+ <bean id="DefaultAuthenticationAudienceClaimsValidator"
+ class="net.shibboleth.oidc.security.jwt.claims.impl.AuthenticationAudienceClaimsValidator"
+ p:endpointTargets="%{idp.oauth2.jwtAuth.audienceValidator.endpointTargets:/profile/oauth2/introspection,/profile/oauth2/revocation}"
+ p:endpointReplacement="/profile/oidc/token">
<property name="audienceLookupStrategy">
<bean parent="shibboleth.BiFunctions.Expression"
c:expression="#custom.getRequestURL().toString()"
@@ -534,7 +536,7 @@
<ref bean="IssuedAtClaimsValidator" />
<ref bean="IssuerClaimsValidator" />
<ref bean="SubjectClaimsValidator" />
- <ref bean="AudienceClaimsValidator" />
+ <ref bean="%{idp.oauth2.jwtAuth.audienceValidator:DefaultAuthenticationAudienceClaimsValidator}" />
<ref bean="JWTIdentifierClaimsValidator" />
</util:list>
diff --git a/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidc.properties b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidc.properties
index 34df0fb0..2e131d9b 100644
--- a/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidc.properties
+++ b/idp-oidc-extension-impl/src/main/resources/net/shibboleth/idp/plugin/oidc/op/conf/oidc.properties
@@ -155,4 +155,9 @@ idp.oidc.subject.salt = this_too_should_be_ch4ng3d
#idp.oauth2.enforceRefreshTokenRotation = true
# Revocation method: set to TOKEN to revoke single tokens (defaults to full chain (value = CHAIN))
-#idp.oauth2.revocationMethod = TOKEN
\ No newline at end of file
+#idp.oauth2.revocationMethod = TOKEN
+
+# Bean used to validate audience claim in the JWT authentication.
+#idp.oauth2.jwtAuth.audienceValidator = DefaultAuthenticationAudienceClaimsValidator
+# The default pattern also accepts token endpoint URL as the audience in introspection and revocation endpoints.
+#idp.oauth2.jwtAuth.audienceValidator.endpointTargets = /profile/oauth2/introspection,/profile/oauth2/revocation
\ No newline at end of file
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcClientAuthenticationFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcClientAuthenticationFlowTest.java
index 2680a955..48177765 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcClientAuthenticationFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcClientAuthenticationFlowTest.java
@@ -28,6 +28,7 @@ import java.util.Map;
import org.opensaml.profile.action.EventIds;
import org.springframework.webflow.executor.FlowExecutionResult;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.nimbusds.jose.JOSEException;
@@ -58,10 +59,12 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
String clientIdSaml = "mockSamlClientId";
String clientSecretSaml = "mockClientSecretmockClientSecretmockClientSecret";
- String jwtAud = "http://localhost";
+ String jwtAud;
+ String issuer = "https://op.example.org";
public AbstractOidcClientAuthenticationFlowTest(final String flowId) {
super(flowId);
+ jwtAud = "http://localhost/idp/profile/" + flowId;
}
protected void populateClientAssertionParams(final Map<String, String> requestParameters,
@@ -69,6 +72,11 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
requestParameters.put("client_assertion", jwt.serialize());
requestParameters.put("client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer");
}
+
+ @BeforeMethod
+ public void setupRequestURI() {
+ request.setRequestURI("/idp/profile/" + flowId);
+ }
@Test
public void testInvalidSecretJWT_missingSub() throws Exception {
@@ -152,6 +160,22 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
assertErrorDescriptionContains(result, getErrorDetaisForJWTValidation().getSecond());
}
+ @Test
+ public void testValidSecretJWTHS256_TokenEndpointAudience() throws Exception {
+ final SignedJWT jwt = createSecretJWT(validClaimsSet("http://localhost/idp/profile/oidc/token"), clientSecret, JWSAlgorithm.HS256);
+ final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+ ClientAuthenticationMethod.CLIENT_SECRET_JWT);
+ assertSuccessResponse(result);
+ }
+
+ @Test
+ public void testValidSecretJWTHS256_IssuerAudience() throws Exception {
+ final SignedJWT jwt = createSecretJWT(validClaimsSet(issuer), clientSecret, JWSAlgorithm.HS256);
+ final FlowExecutionResult result = launchWithJwtAuthentication(jwt, null,
+ ClientAuthenticationMethod.CLIENT_SECRET_JWT);
+ assertSuccessResponse(result);
+ }
+
@Test
public void testValidSecretJWTHS256_noRegisteredAlg() throws Exception {
final SignedJWT jwt = createSecretJWT(validClaimsSet(), clientSecret, JWSAlgorithm.HS256);
@@ -591,10 +615,14 @@ public abstract class AbstractOidcClientAuthenticationFlowTest extends AbstractO
}
protected JWTClaimsSet validClaimsSet() {
+ return validClaimsSet(jwtAud);
+ }
+
+ protected JWTClaimsSet validClaimsSet(final String audience) {
return new JWTClaimsSet.Builder()
.subject(clientId)
.issuer(clientId)
- .audience(jwtAud)
+ .audience(audience)
.expirationTime(Date.from(Instant.now().plusSeconds(600)))
.jwtID(idGenerator.generateIdentifier())
.build();
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/IntrospectionFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/IntrospectionFlowTest.java
index 387c6d2e..442d7825 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/IntrospectionFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/IntrospectionFlowTest.java
@@ -439,6 +439,7 @@ public class IntrospectionFlowTest extends AbstractOidcClientAuthenticationFlowT
protected void assertSuccessResponse(final FlowExecutionResult result) {
final TokenIntrospectionSuccessResponse resp =
parseSuccessResponse(result, TokenIntrospectionSuccessResponse.class);
+ Assert.assertNotNull(resp);
Assert.assertTrue(resp.isActive());
Assert.assertEquals(resp.getClientID().getValue(), clientId);
Assert.assertEquals(resp.getScope(), scope);
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RevocationFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RevocationFlowTest.java
index 2d331456..84f0438c 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RevocationFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/RevocationFlowTest.java
@@ -301,6 +301,6 @@ public class RevocationFlowTest extends AbstractOidcClientAuthenticationFlowTest
}
protected void assertSuccessResponse(final FlowExecutionResult result) {
- parseSuccessResponse(result, OAuth2RevocationSuccessResponse.class);
+ Assert.assertNotNull(parseSuccessResponse(result, OAuth2RevocationSuccessResponse.class));
}
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list