[java-idp-oidc] branch main updated: Add JWT unit tests.
Scott Cantor
cantor.2 at osu.edu
Thu Feb 3 13:58:26 UTC 2022
This is an automated email from the git hooks/post-receive script.
scantor 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=3301a9715b7479ea6ee8c2d60bbd639b28ee0b72
The following commit(s) were added to refs/heads/main by this push:
new 3301a971 Add JWT unit tests.
3301a971 is described below
commit 3301a9715b7479ea6ee8c2d60bbd639b28ee0b72
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Feb 3 08:58:19 2022 -0500
Add JWT unit tests.
---
.../FormOutboundIntrospectionResponseMessage.java | 5 +-
.../FormOutboundRevokeTokenResponseMessage.java | 6 +-
.../oidc/op/profile/flow/RevocationFlowTest.java | 95 ++++++++++++++++++++++
3 files changed, 99 insertions(+), 7 deletions(-)
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundIntrospectionResponseMessage.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundIntrospectionResponseMessage.java
index d2beb1bc..3149edf2 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundIntrospectionResponseMessage.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundIntrospectionResponseMessage.java
@@ -28,7 +28,6 @@ import org.slf4j.LoggerFactory;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.oauth2.sdk.Scope;
-import com.nimbusds.oauth2.sdk.TokenIntrospectionRequest;
import com.nimbusds.oauth2.sdk.TokenIntrospectionSuccessResponse;
import com.nimbusds.oauth2.sdk.id.Audience;
import com.nimbusds.oauth2.sdk.id.ClientID;
@@ -37,14 +36,14 @@ import com.nimbusds.oauth2.sdk.id.Subject;
import com.nimbusds.oauth2.sdk.token.AccessTokenType;
import net.shibboleth.idp.plugin.oidc.op.oauth2.messaging.context.OAuth2TokenMgmtResponseContext;
-import net.shibboleth.idp.plugin.oidc.op.profile.impl.AbstractOIDCRequestAction;
import net.shibboleth.idp.plugin.oidc.op.token.support.TokenClaimsSet;
+import net.shibboleth.idp.profile.AbstractProfileAction;
/**
* Action that forms outbound token introspection success message. Formed message is set to
* {@link ProfileRequestContext#getOutboundMessageContext()}.
*/
-public class FormOutboundIntrospectionResponseMessage extends AbstractOIDCRequestAction<TokenIntrospectionRequest> {
+public class FormOutboundIntrospectionResponseMessage extends AbstractProfileAction {
/** Class logger. */
@Nonnull private Logger log = LoggerFactory.getLogger(FormOutboundIntrospectionResponseMessage.class);
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundRevokeTokenResponseMessage.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundRevokeTokenResponseMessage.java
index a34e4f24..ffcf9343 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundRevokeTokenResponseMessage.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/oauth2/profile/impl/FormOutboundRevokeTokenResponseMessage.java
@@ -21,16 +21,14 @@ import javax.annotation.Nonnull;
import org.opensaml.profile.context.ProfileRequestContext;
-import com.nimbusds.oauth2.sdk.TokenRevocationRequest;
-
import net.shibboleth.idp.plugin.oidc.op.oauth2.messaging.impl.OAuth2RevocationSuccessResponse;
-import net.shibboleth.idp.plugin.oidc.op.profile.impl.AbstractOIDCRequestAction;
+import net.shibboleth.idp.profile.AbstractProfileAction;
/**
* Action that forms outbound token revocation success message. Formed message is set to
* {@link ProfileRequestContext#getOutboundMessageContext()}.
*/
-public class FormOutboundRevokeTokenResponseMessage extends AbstractOIDCRequestAction<TokenRevocationRequest> {
+public class FormOutboundRevokeTokenResponseMessage extends AbstractProfileAction {
/** {@inheritDoc} */
@Override
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 c6f5d53e..a8326f85 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
@@ -20,8 +20,10 @@ package net.shibboleth.idp.plugin.oidc.op.profile.flow;
import java.io.IOException;
import java.net.URISyntaxException;
import java.security.NoSuchAlgorithmException;
+import java.time.Instant;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.opensaml.storage.StorageService;
@@ -31,18 +33,24 @@ import org.springframework.webflow.executor.FlowExecutionResult;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
+import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jwt.SignedJWT;
import com.nimbusds.oauth2.sdk.OAuth2Error;
import com.nimbusds.oauth2.sdk.ParseException;
import com.nimbusds.oauth2.sdk.Scope;
import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod;
+import com.nimbusds.oauth2.sdk.id.ClientID;
import net.shibboleth.idp.plugin.oidc.op.oauth2.messaging.impl.OAuth2RevocationSuccessResponse;
+import net.shibboleth.idp.plugin.oidc.op.token.support.AccessTokenClaimsSet;
+import net.shibboleth.oidc.security.credential.JWKCredential;
import net.shibboleth.utilities.java.support.collection.Pair;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.security.DataSealerException;
+// Checkstyle: ThrowsCount OFF
+
/**
* Unit tests for the OAuth2 revocation flow.
*/
@@ -58,6 +66,10 @@ public class RevocationFlowTest extends AbstractOidcClientAuthenticationFlowTest
Scope scope = Scope.parse("openid profile email");
+ @Autowired
+ @Qualifier("testbed.DefaultRSSigningCredential")
+ private JWKCredential signingKey = null;
+
@Autowired
@Qualifier("shibboleth.StorageService")
StorageService storageService;
@@ -144,7 +156,90 @@ public class RevocationFlowTest extends AbstractOidcClientAuthenticationFlowTest
return new Pair<>("invalid_client", "Client authentication failed");
}
+ @Test
+ public void testSuccessJWTNoAudience() throws JOSEException, IOException {
+ storeMetadata(storageService, clientId, clientSecret, scope);
+ setBasicAuth(clientId, clientSecret);
+ setHttpFormRequest("POST", Map.of(
+ "token",
+ buildJWTToken(clientId, "sub", scope, null, signingKey.getPrivateKey(), "RS256").toJSONObject()
+ .getAsString("access_token"),
+ "token_type",
+ "access_token"));
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ parseSuccessResponse(result, OAuth2RevocationSuccessResponse.class);
+ }
+ @Test
+ public void testSuccessJWTAudience() throws JOSEException, IOException {
+ storeMetadata(storageService, clientId, clientSecret, scope);
+ setBasicAuth(clientId, clientSecret);
+ setHttpFormRequest("POST", Map.of(
+ "token",
+ buildJWTToken("https://sp2.example.org", "sub", scope,
+ List.of("https://sp.example.org", clientId),
+ signingKey.getPrivateKey(), "RS256").toJSONObject()
+ .getAsString("access_token"),
+ "token_type",
+ "access_token"));
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ parseSuccessResponse(result, OAuth2RevocationSuccessResponse.class);
+ }
+
+ @Test
+ public void testSuccessJWTExpired() throws JOSEException, IOException {
+ storeMetadata(storageService, clientId, clientSecret, scope);
+ setBasicAuth(clientId, clientSecret);
+ final AccessTokenClaimsSet claims = new AccessTokenClaimsSet.Builder()
+ .setJWTID(idGenerator)
+ .setClientID(new ClientID(clientId))
+ .setIssuer("https://op.example.org")
+ .setSubject(clientId)
+ .setIssuedAt(Instant.now().minusSeconds(300))
+ .setNotBefore(Instant.now().minusSeconds(300))
+ .setExpiresAt(Instant.now().minusSeconds(200))
+ .setAuthenticationTime(Instant.now())
+ .setScope(scope)
+ .build();
+ setHttpFormRequest("POST", Map.of(
+ "token",
+ buildJWTToken(claims, signingKey.getPrivateKey(), "RS256").toJSONObject().getAsString("access_token"),
+ "token_type",
+ "access_token"));
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ parseSuccessResponse(result, OAuth2RevocationSuccessResponse.class);
+ }
+
+ @Test
+ public void testSuccessJWTNotAuthorized() throws JOSEException, IOException {
+ storeMetadata(storageService, clientId, clientSecret, scope);
+ setBasicAuth(clientId, clientSecret);
+ setHttpFormRequest("POST", Map.of(
+ "token",
+ buildJWTToken("https://sp3.example.org", "sub", scope,
+ List.of("https://sp.example.org", "https://sp2.example.org"),
+ signingKey.getPrivateKey(), "RS256").toJSONObject()
+ .getAsString("access_token"),
+ "token_type",
+ "access_token"));
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ parseSuccessResponse(result, OAuth2RevocationSuccessResponse.class);
+ }
+
+ @Test
+ public void testSuccessJWTWrongKey() throws JOSEException, IOException {
+ storeMetadata(storageService, clientId, clientSecret, scope);
+ setBasicAuth(clientId, clientSecret);
+ setHttpFormRequest("POST", Map.of(
+ "token",
+ buildJWTToken(clientId, "sub", scope, null, rsaPrivateKey, "RS256").toJSONObject()
+ .getAsString("access_token"),
+ "token_type",
+ "access_token"));
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ parseSuccessResponse(result, OAuth2RevocationSuccessResponse.class);
+ }
+
@Test
public void testFailedAuthentication() throws IOException, NoSuchAlgorithmException, URISyntaxException,
DataSealerException, ComponentInitializationException {
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list