[java-idp-oidc] branch main updated: Add more unit tests related to scope validation.
Scott Cantor
cantor.2 at osu.edu
Wed Jan 5 17:02:37 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=70084dd92c873ff65cae6f3e76ef95215033031a
The following commit(s) were added to refs/heads/main by this push:
new 70084dd9 Add more unit tests related to scope validation.
70084dd9 is described below
commit 70084dd92c873ff65cae6f3e76ef95215033031a
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Jan 5 12:02:34 2022 -0500
Add more unit tests related to scope validation.
---
.../profile/impl/SetSubjectToResponseContext.java | 3 +-
.../plugin/oidc/op/profile/impl/ValidateScope.java | 13 ++-
.../oidc/op/profile/flow/AbstractOidcFlowTest.java | 41 ++++-----
.../oidc/op/profile/flow/AuthorizeFlowTest.java | 96 +++++++++++++---------
.../op/profile/flow/IntrospectionFlowTest.java | 53 ++++++------
.../oidc/op/profile/flow/RevocationFlowTest.java | 21 +++--
.../plugin/oidc/op/profile/flow/TokenFlowTest.java | 53 ++++++++++--
.../plugin/oidc/op/profile/flow/UserInfoTest.java | 20 +++--
.../profile/impl/BaseOIDCResponseActionTest.java | 2 +-
.../impl/SetSubjectToResponseContextTest.java | 4 +-
.../oidc/op/profile/impl/ValidateScopeTest.java | 16 +++-
11 files changed, 206 insertions(+), 116 deletions(-)
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/SetSubjectToResponseContext.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/SetSubjectToResponseContext.java
index f3ab901f..a0b728a4 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/SetSubjectToResponseContext.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/SetSubjectToResponseContext.java
@@ -22,6 +22,7 @@ import java.util.function.Function;
import javax.annotation.Nonnull;
import net.shibboleth.idp.plugin.oidc.op.messaging.context.OIDCAuthenticationResponseContext;
+import net.shibboleth.idp.plugin.oidc.op.profile.OidcEventIds;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.TokenRequestSubjectLookupFunction;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
@@ -84,7 +85,7 @@ public class SetSubjectToResponseContext extends AbstractOIDCResponseAction {
final String subject = subjectLookupStrategy.apply(profileRequestContext);
if (subject == null) {
log.error("{} Subject may not be null", getLogPrefix());
- ActionSupport.buildEvent(profileRequestContext, EventIds.INVALID_PROFILE_CTX);
+ ActionSupport.buildEvent(profileRequestContext, OidcEventIds.INVALID_SUBJECT);
return;
}
getOidcResponseContext().setSubject(subject);
diff --git a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateScope.java b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateScope.java
index 95830de9..931efe44 100644
--- a/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateScope.java
+++ b/idp-oidc-extension-impl/src/main/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateScope.java
@@ -40,14 +40,21 @@ import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.logic.Constraint;
/**
- * Action that validates requested scopes are registered ones and stores the resulting set in the
- * response context.
+ * Action that validates requested and previously granted scopes are also registered in client metadata
+ * and stores the resulting set in the response context.
+ *
+ * <p>Requested scopes come from the inbound message and are possible but optional for both
+ * authorization and token requests. They come from lookup functions aware of each message type.</p>
+ *
+ * <p>Previously granted scopes are stored in the response context's slow for previous authorization
+ * grant claims. In the case where no scopes are explicitly requested, we still filter the previous
+ * grants against the metadata.</p>
*
* <p>Explicitly requested scopes are also filtered against, and override, any scopes previously
* validated as part of an authorization grant claim set. If this occurs, any grant-borne claims
* are removed because the association to specific scopes is gone by this point.</p>
*
- * <p>The "offline_access" scope is ignored in authentication endpoint validation unless the
+ * <p>The "offline_access" scope is ignored and stripped for the authentication endpoint unless the
* response type includes "code".</p>
*/
public class ValidateScope extends AbstractOIDCAuthenticationResponseAction {
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcFlowTest.java
index 7feb922d..c159f32d 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AbstractOidcFlowTest.java
@@ -76,8 +76,8 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
private String flowId;
- protected AbstractOidcFlowTest(final String flowId) {
- this.flowId = flowId;
+ protected AbstractOidcFlowTest(final String id) {
+ flowId = id;
}
/**
@@ -160,29 +160,31 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
}
protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
- final String... redirectUri) throws IOException {
- storeMetadata(storageService, clientId, secret, null, ClientAuthenticationMethod.CLIENT_SECRET_BASIC, null,
- null, redirectUri);
+ final Scope scope, final String... redirectUri) throws IOException {
+ storeMetadata(storageService, clientId, secret, scope, null, ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
+ null, null, redirectUri);
}
+// Checkstyle: ParameterNumber OFF
protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
- final JWSAlgorithm tokenEndpointSigAlg, final ClientAuthenticationMethod tokenEndpointMethod,
- final String... redirectUri)
- throws IOException {
- storeMetadata(storageService, clientId, secret, tokenEndpointSigAlg, tokenEndpointMethod, null, null, redirectUri);
+ final Scope scope, final JWSAlgorithm tokenEndpointSigAlg,
+ final ClientAuthenticationMethod tokenEndpointMethod, final String... redirectUri) throws IOException {
+ storeMetadata(storageService, clientId, secret, scope, tokenEndpointSigAlg, tokenEndpointMethod, null, null,
+ redirectUri);
}
protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
- final JWSAlgorithm tokenEndpointSigAlg, final ClientAuthenticationMethod tokenEndpointMethod,
- final JWSAlgorithm userInfoSigAlg, final String... redirectUri)
- throws IOException {
- storeMetadata(storageService, clientId, secret, tokenEndpointSigAlg, tokenEndpointMethod, userInfoSigAlg, null, redirectUri);
+ final Scope scope, final JWSAlgorithm tokenEndpointSigAlg,
+ final ClientAuthenticationMethod tokenEndpointMethod, final JWSAlgorithm userInfoSigAlg,
+ final String... redirectUri) throws IOException {
+ storeMetadata(storageService, clientId, secret, scope, tokenEndpointSigAlg, tokenEndpointMethod, userInfoSigAlg,
+ null, redirectUri);
}
protected void storeMetadata(final StorageService storageService, final String clientId, final String secret,
- final JWSAlgorithm tokenEndpointSigAlg, final ClientAuthenticationMethod tokenEndpointMethod,
- final JWSAlgorithm userInfoSigAlg, final RSAPublicKey publicKey, final String... redirectUri)
- throws IOException {
+ final Scope scope, final JWSAlgorithm tokenEndpointSigAlg,
+ final ClientAuthenticationMethod tokenEndpointMethod, final JWSAlgorithm userInfoSigAlg,
+ final RSAPublicKey publicKey, final String... redirectUri) throws IOException {
final OIDCClientMetadata metadata = new OIDCClientMetadata();
metadata.setGrantTypes(new HashSet<GrantType>(Arrays.asList(GrantType.AUTHORIZATION_CODE,
GrantType.REFRESH_TOKEN)));
@@ -198,7 +200,7 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
responseTypes.add(new ResponseType("code"));
metadata.setResponseTypes(responseTypes);
metadata.setRedirectionURIs(uris);
- metadata.setScope(Scope.parse("openid profile email"));
+ metadata.setScope(scope);
metadata.setTokenEndpointAuthJWSAlg(tokenEndpointSigAlg);
metadata.setTokenEndpointAuthMethod(tokenEndpointMethod);
metadata.setUserInfoJWSAlg(userInfoSigAlg);
@@ -207,8 +209,8 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
information = new OIDCClientInformation(new ClientID(clientId), new Date(),
metadata, new Secret(secret));
} else {
- RSAKey rsaKey = new RSAKey.Builder(publicKey).build();
- JWKSet jwkSet = new JWKSet(rsaKey);
+ final RSAKey rsaKey = new RSAKey.Builder(publicKey).build();
+ final JWKSet jwkSet = new JWKSet(rsaKey);
metadata.setJWKSet(jwkSet);
information = new OIDCClientInformation(new ClientID(clientId), metadata);
}
@@ -216,6 +218,7 @@ public abstract class AbstractOidcFlowTest extends AbstractFlowTest {
information.toJSONObject().toJSONString(), System.currentTimeMillis() + (60 * 60 * 1000));
}
+// Checkstyle: ParameterNumber ON
protected void removeMetadata(final StorageService storageService, final String clientId) throws IOException {
storageService.delete(BaseStorageServiceClientInformationComponent.CONTEXT_NAME, clientId);
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AuthorizeFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AuthorizeFlowTest.java
index 441c60dc..01bf40b5 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AuthorizeFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/AuthorizeFlowTest.java
@@ -36,7 +36,9 @@ import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.PlainJWT;
import com.nimbusds.jwt.SignedJWT;
+import com.nimbusds.oauth2.sdk.ErrorResponse;
import com.nimbusds.oauth2.sdk.ParseException;
+import com.nimbusds.oauth2.sdk.Scope;
import com.nimbusds.openid.connect.sdk.AuthenticationResponse;
import com.nimbusds.openid.connect.sdk.AuthenticationSuccessResponse;
@@ -52,6 +54,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
String redirectUri = "https://example.org/cb";
String clientId = "mockClientId";
String clientSecret = "mockClientSecretmockClientSecretmockClientSecretmockClientSecretmockClientSecret";
+ Scope scope = Scope.parse("openid profile email");
@Autowired
@Qualifier("shibboleth.StorageService")
@@ -71,32 +74,48 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
request.setMethod("GET");
request.setQueryString("client_id=mockClientId&response_type=code&scope=openid%20profile&redirect_uri="
+ redirectUri);
- storeMetadata(storageService, clientId, clientSecret, redirectUri);
+ storeMetadata(storageService, clientId, clientSecret, scope, redirectUri);
initializeThreadLocals();
- FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
- AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
+ final AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
Assert.assertEquals(successResponse.getRedirectionURI().toString(), redirectUri);
Assert.assertNull(successResponse.getIDToken());
Assert.assertNull(successResponse.getAccessToken());
Assert.assertNotNull(successResponse.getAuthorizationCode());
}
+ @Test
+ public void testWithAuthorizationCodeFlowNoScopes() throws IOException, ParseException, SessionException {
+ request.setMethod("GET");
+ request.setQueryString("client_id=mockClientId&response_type=code&scope=openid%20profile&redirect_uri="
+ + redirectUri);
+ storeMetadata(storageService, clientId, clientSecret, null, redirectUri);
+
+ initializeThreadLocals();
+
+ // TODO: Speculation this should fail more explicitly if openid scope isn't valid.
+
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ assertErrorCode(result, "invalid_request");
+ assertErrorDescriptionContains(result, "InvalidSubject");
+ }
+
@Test
public void testWithAuthorizationCodeFlowWithIDTokenClaims() throws IOException, ParseException, SessionException {
request.setMethod("GET");
request.setQueryString("client_id=mockClientId&response_type=code&scope=openid%20profile"
+ "&claims=%7B%22id_token%22%3A%7B%22email%22%3A%7B%22essential%22%3Atrue%7D%7D%7D"
+ "&redirect_uri=" + redirectUri);
- storeMetadata(storageService, clientId, clientSecret, redirectUri);
+ storeMetadata(storageService, clientId, clientSecret, scope, redirectUri);
initializeThreadLocals();
- FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
- AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
+ final AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
Assert.assertEquals(successResponse.getRedirectionURI().toString(), redirectUri);
Assert.assertNull(successResponse.getIDToken());
Assert.assertNull(successResponse.getAccessToken());
@@ -109,13 +128,13 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
request.setQueryString("client_id=mockClientId&response_type=code&scope=openid%20profile"
+ "&claims=%7B%22userinfo%22%3A%7B%22email%22%3A%7B%22essential%22%3Atrue%7D%7D%7D"
+ "&redirect_uri=" + redirectUri);
- storeMetadata(storageService, clientId, clientSecret, redirectUri);
+ storeMetadata(storageService, clientId, clientSecret, scope, redirectUri);
initializeThreadLocals();
- FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
- AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
+ final AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
Assert.assertEquals(successResponse.getRedirectionURI().toString(), redirectUri);
Assert.assertNull(successResponse.getIDToken());
Assert.assertNull(successResponse.getAccessToken());
@@ -127,13 +146,13 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
request.setMethod("GET");
request.setQueryString("client_id=mockSamlClientId&response_type=code&scope=openid%20profile&redirect_uri="
+ redirectUri);
- storeMetadata(storageService, clientId, clientSecret, redirectUri);
+ storeMetadata(storageService, clientId, clientSecret, scope, redirectUri);
initializeThreadLocals();
- FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
- AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
+ final AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
Assert.assertEquals(successResponse.getRedirectionURI().toString(), redirectUri);
Assert.assertNull(successResponse.getIDToken());
Assert.assertNull(successResponse.getAccessToken());
@@ -147,14 +166,14 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
+ redirectUri);
initializeThreadLocals();
- FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertFlowExecutionResult(result, FLOW_ID);
Assert.assertEquals(result.getOutcome().getId(), "ErrorView");
}
@Test
public void testWithPlainReqObjectExpired() throws IOException, ParseException, SessionException {
- JWTClaimsSet ro = new JWTClaimsSet.Builder()
+ final JWTClaimsSet ro = new JWTClaimsSet.Builder()
.expirationTime(Date.from(Instant.now().minus(Duration.ofMinutes(5))))
.build();
assertRequestObjectError(new PlainJWT(ro));
@@ -162,29 +181,28 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
@Test
public void testWithPlainReqObjectNbfInFuture() throws IOException, ParseException, SessionException {
- JWTClaimsSet ro = new JWTClaimsSet.Builder()
+ final JWTClaimsSet ro = new JWTClaimsSet.Builder()
.notBeforeTime(Date.from(Instant.now().plus(Duration.ofMinutes(5))))
.build();
assertRequestObjectError(new PlainJWT(ro));
}
@Test
- public void testWithPlainReqObjectOverwriteRedirectUri() throws IOException, ParseException,
- SessionException {
- JWTClaimsSet ro = new JWTClaimsSet.Builder()
+ public void testWithPlainReqObjectOverwriteRedirectUri() throws IOException, ParseException, SessionException {
+ final JWTClaimsSet ro = new JWTClaimsSet.Builder()
.claim("redirect_uri", redirectUri)
.build();
- PlainJWT requestObject = new PlainJWT(ro);
+ final PlainJWT requestObject = new PlainJWT(ro);
request.setMethod("GET");
request.setQueryString("client_id=mockClientId&response_type=code&scope=openid%20profile&redirect_uri="
+ "https://invalid.org/cb&request=" + requestObject.serialize());
- storeMetadata(storageService, clientId, clientSecret, redirectUri);
+ storeMetadata(storageService, clientId, clientSecret, scope, redirectUri);
initializeThreadLocals();
- FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
- AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
+ final AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
Assert.assertEquals(successResponse.getRedirectionURI().toString(), redirectUri);
Assert.assertNull(successResponse.getIDToken());
Assert.assertNull(successResponse.getAccessToken());
@@ -194,7 +212,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
@Test
public void testWithSignedReqObjectNoIssuer() throws IOException, ParseException, SessionException,
JOSEException {
- JWTClaimsSet ro = new JWTClaimsSet.Builder()
+ final JWTClaimsSet ro = new JWTClaimsSet.Builder()
.audience("https://op.example.org")
.build();
assertRequestObjectError(createSecretJWT(ro, clientSecret));
@@ -203,7 +221,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
@Test
public void testWithSignedReqObjectNoAudience() throws IOException, ParseException, SessionException,
JOSEException {
- JWTClaimsSet ro = new JWTClaimsSet.Builder()
+ final JWTClaimsSet ro = new JWTClaimsSet.Builder()
.issuer(clientId)
.build();
assertRequestObjectError(createSecretJWT(ro, clientSecret));
@@ -212,7 +230,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
@Test
public void testWithSignedReqObjectWrongIssuer() throws IOException, ParseException, SessionException,
JOSEException {
- JWTClaimsSet ro = new JWTClaimsSet.Builder()
+ final JWTClaimsSet ro = new JWTClaimsSet.Builder()
.audience("https://op.example.org")
.issuer("invalid")
.build();
@@ -222,7 +240,7 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
@Test
public void testWithSignedReqObjectWrongAudience() throws IOException, ParseException, SessionException,
JOSEException {
- JWTClaimsSet ro = new JWTClaimsSet.Builder()
+ final JWTClaimsSet ro = new JWTClaimsSet.Builder()
.audience("https://invalid.org")
.issuer(clientId)
.build();
@@ -232,22 +250,22 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
@Test
public void testWithSignedReqObjectOverwriteRedirectUri() throws IOException, ParseException,
SessionException, JOSEException {
- JWTClaimsSet ro = new JWTClaimsSet.Builder()
+ final JWTClaimsSet ro = new JWTClaimsSet.Builder()
.audience("https://op.example.org")
.issuer(clientId)
.claim("redirect_uri", redirectUri)
.build();
- SignedJWT requestObject = createSecretJWT(ro, clientSecret);
+ final SignedJWT requestObject = createSecretJWT(ro, clientSecret);
request.setMethod("GET");
request.setQueryString("client_id=mockClientId&response_type=code&scope=openid%20profile&redirect_uri="
+ "https://invalid.org/cb&request=" + requestObject.serialize());
- storeMetadata(storageService, clientId, clientSecret, redirectUri);
+ storeMetadata(storageService, clientId, clientSecret, scope, redirectUri);
initializeThreadLocals();
- FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
- AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final AuthenticationResponse responseMessage = parseSuccessResponse(result, AuthenticationResponse.class);
+ final AuthenticationSuccessResponse successResponse = responseMessage.toSuccessResponse();
Assert.assertEquals(successResponse.getRedirectionURI().toString(), redirectUri);
Assert.assertNull(successResponse.getIDToken());
Assert.assertNull(successResponse.getAccessToken());
@@ -258,10 +276,10 @@ public class AuthorizeFlowTest extends AbstractOidcFlowTest {
request.setMethod("GET");
request.setQueryString("client_id=mockClientId&response_type=code&scope=openid%20profile&redirect_uri="
+ redirectUri + "&request=" + requestObject.serialize());
- storeMetadata(storageService, clientId, clientSecret, redirectUri);
+ storeMetadata(storageService, clientId, clientSecret, scope, redirectUri);
initializeThreadLocals();
- FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertFlowExecutionResult(result, FLOW_ID);
Assert.assertEquals(result.getOutcome().getId(), "ErrorView");
}
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 b897750c..7156f0ad 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
@@ -60,6 +60,8 @@ public class IntrospectionFlowTest extends AbstractOidcClientAuthenticationFlowT
String clientIdSaml = "mockSamlClientId";
String clientSecretSaml = "mockClientSecretmockClientSecretmockClientSecret";
+ Scope scope = Scope.parse("openid profile email");
+
@Autowired
@Qualifier("shibboleth.StorageService")
StorageService storageService;
@@ -69,14 +71,13 @@ public class IntrospectionFlowTest extends AbstractOidcClientAuthenticationFlowT
}
@BeforeMethod
- public void setup() throws IOException, NoSuchAlgorithmException, URISyntaxException, DataSealerException,
- ComponentInitializationException {
+ public void setup() throws IOException {
removeMetadata(storageService, clientId);
}
@Test
- public void testUntrustedClient() throws IOException, NoSuchAlgorithmException, URISyntaxException,
- DataSealerException, ComponentInitializationException {
+ public void testUntrustedClient() throws NoSuchAlgorithmException, URISyntaxException, DataSealerException,
+ ComponentInitializationException {
setBasicAuth(clientId, clientSecret);
setHttpFormRequest("POST", Collections.singletonMap("token",
super.buildToken(clientId, "sub", Scope.parse("openid")).toJSONObject().getAsString("access_token")));
@@ -87,7 +88,7 @@ public class IntrospectionFlowTest extends AbstractOidcClientAuthenticationFlowT
@Test
public void testInvalidMessage() throws IOException, NoSuchAlgorithmException, URISyntaxException,
DataSealerException, ComponentInitializationException {
- storeMetadata(storageService, clientId, clientSecret);
+ storeMetadata(storageService, clientId, clientSecret, scope);
setBasicAuth(clientId, clientSecret);
setHttpFormRequest("POST", Collections.singletonMap("token_not",
super.buildToken(clientId, "sub", Scope.parse("openid")).toJSONObject().getAsString("access_token")));
@@ -98,12 +99,13 @@ public class IntrospectionFlowTest extends AbstractOidcClientAuthenticationFlowT
@Test
public void testSuccess() throws IOException, NoSuchAlgorithmException, URISyntaxException, DataSealerException,
ComponentInitializationException {
- storeMetadata(storageService, clientId, clientSecret);
+ storeMetadata(storageService, clientId, clientSecret, scope);
setBasicAuth(clientId, clientSecret);
setHttpFormRequest("POST", Collections.singletonMap("token",
super.buildToken(clientId, "sub", Scope.parse("openid")).toJSONObject().getAsString("access_token")));
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- TokenIntrospectionSuccessResponse resp = parseSuccessResponse(result, TokenIntrospectionSuccessResponse.class);
+ final TokenIntrospectionSuccessResponse resp =
+ parseSuccessResponse(result, TokenIntrospectionSuccessResponse.class);
Assert.assertEquals(resp.getClientID().getValue(), clientId);
Assert.assertTrue(resp.isActive());
}
@@ -115,7 +117,8 @@ public class IntrospectionFlowTest extends AbstractOidcClientAuthenticationFlowT
setHttpFormRequest("POST", Collections.singletonMap("token",
super.buildToken(clientIdSaml, "sub", Scope.parse("openid")).toJSONObject().getAsString("access_token")));
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- TokenIntrospectionSuccessResponse resp = parseSuccessResponse(result, TokenIntrospectionSuccessResponse.class);
+ TokenIntrospectionSuccessResponse resp =
+ parseSuccessResponse(result, TokenIntrospectionSuccessResponse.class);
Assert.assertEquals(resp.getClientID().getValue(), clientIdSaml);
Assert.assertTrue(resp.isActive());
}
@@ -123,13 +126,14 @@ public class IntrospectionFlowTest extends AbstractOidcClientAuthenticationFlowT
@Test
public void testSuccessWithLegacyToken() throws IOException, NoSuchAlgorithmException, URISyntaxException,
DataSealerException, ComponentInitializationException {
- storeMetadata(storageService, clientId, clientSecret);
+ storeMetadata(storageService, clientId, clientSecret, scope);
setBasicAuth(clientId, clientSecret);
setHttpFormRequest("POST", Collections.singletonMap("token",
super.buildLegacyToken(clientId, "sub",
Scope.parse("openid")).toJSONObject().getAsString("access_token")));
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- TokenIntrospectionSuccessResponse resp = parseSuccessResponse(result, TokenIntrospectionSuccessResponse.class);
+ final TokenIntrospectionSuccessResponse resp =
+ parseSuccessResponse(result, TokenIntrospectionSuccessResponse.class);
Assert.assertEquals(resp.getClientID().getValue(), clientId);
Assert.assertTrue(resp.isActive());
}
@@ -137,13 +141,14 @@ public class IntrospectionFlowTest extends AbstractOidcClientAuthenticationFlowT
@Test
public void testSuccessWithLegacyConsentToken() throws IOException, NoSuchAlgorithmException, URISyntaxException,
DataSealerException, ComponentInitializationException {
- storeMetadata(storageService, clientId, clientSecret);
+ storeMetadata(storageService, clientId, clientSecret, scope);
setBasicAuth(clientId, clientSecret);
setHttpFormRequest("POST", Collections.singletonMap("token",
super.buildLegacyToken(clientId, "sub", Scope.parse("openid"),
"mail").toJSONObject().getAsString("access_token")));
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- TokenIntrospectionSuccessResponse resp = parseSuccessResponse(result, TokenIntrospectionSuccessResponse.class);
+ final TokenIntrospectionSuccessResponse resp =
+ parseSuccessResponse(result, TokenIntrospectionSuccessResponse.class);
Assert.assertEquals(resp.getClientID().getValue(), clientId);
Assert.assertTrue(resp.isActive());
}
@@ -151,11 +156,12 @@ public class IntrospectionFlowTest extends AbstractOidcClientAuthenticationFlowT
@Test
public void testUnidentifiedToken() throws IOException, NoSuchAlgorithmException, URISyntaxException,
DataSealerException, ComponentInitializationException {
- storeMetadata(storageService, clientId, clientSecret);
+ storeMetadata(storageService, clientId, clientSecret, scope);
setBasicAuth(clientId, clientSecret);
setHttpFormRequest("POST", Collections.singletonMap("token", "unknowntoken"));
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- TokenIntrospectionSuccessResponse resp = parseSuccessResponse(result, TokenIntrospectionSuccessResponse.class);
+ final TokenIntrospectionSuccessResponse resp =
+ parseSuccessResponse(result, TokenIntrospectionSuccessResponse.class);
Assert.assertNull(resp.getClientID());
Assert.assertFalse(resp.isActive());
}
@@ -163,37 +169,38 @@ public class IntrospectionFlowTest extends AbstractOidcClientAuthenticationFlowT
@Test
public void testFailedAuthentication() throws IOException, NoSuchAlgorithmException, URISyntaxException,
DataSealerException, ComponentInitializationException {
- storeMetadata(storageService, clientId, clientSecret);
+ storeMetadata(storageService, clientId, clientSecret, scope);
setBasicAuth(clientId, clientSecret + "X");
setHttpFormRequest("POST", Collections.singletonMap("token",
super.buildToken(clientId, "sub", Scope.parse("openid")).toJSONObject().getAsString("access_token")));
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
- TokenIntrospectionErrorResponse resp = (TokenIntrospectionErrorResponse) parseErrorResponse(result);
+ final TokenIntrospectionErrorResponse resp = (TokenIntrospectionErrorResponse) parseErrorResponse(result);
Assert.assertEquals(resp.getErrorObject().getCode(), OAuth2Error.INVALID_CLIENT_CODE);
}
protected FlowExecutionResult launchWithJwtAuthentication(final SignedJWT jwt, final JWSAlgorithm algorithm,
final ClientAuthenticationMethod method) throws Exception {
if (ClientAuthenticationMethod.CLIENT_SECRET_JWT.equals(method)) {
- storeMetadata(storageService, clientId, clientSecret, algorithm, method);
+ storeMetadata(storageService, clientId, clientSecret, scope, algorithm, method);
} else {
- storeMetadata(storageService, clientId, null, algorithm, method, null, rsaPublicKey);
+ storeMetadata(storageService, clientId, null, scope, algorithm, method, null, rsaPublicKey);
}
- final String accessToken = super.buildToken(clientId, "sub", Scope.parse("openid")).toJSONObject().getAsString("access_token");
- Map<String, String> requestParameters = createRequestParameters(accessToken, clientId);
+ final String accessToken =
+ super.buildToken(clientId, "sub", Scope.parse("openid")).toJSONObject().getAsString("access_token");
+ final Map<String, String> requestParameters = createRequestParameters(accessToken, clientId);
populateClientAssertionParams(requestParameters, jwt);
setHttpFormRequest("POST", requestParameters);
return flowExecutor.launchExecution(FLOW_ID, null, externalContext);
}
- protected Map<String, String> createRequestParameters(final String token, final String clientId) {
- final Map<String, String> result = new HashMap<>();
+ protected Map<String,String> createRequestParameters(final String token, final String clientId) {
+ final Map<String,String> result = new HashMap<>();
result.put("token", token);
result.put("client_id", clientId);
return result;
}
- protected Pair<String, String> getErrorDetaisForJWTValidation() {
+ protected Pair<String,String> getErrorDetaisForJWTValidation() {
return new Pair<>("invalid_client", "Client authentication failed");
}
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 f458edb7..f2658e05 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
@@ -57,6 +57,8 @@ public class RevocationFlowTest extends AbstractOidcClientAuthenticationFlowTest
String clientIdSaml = "mockSamlClientId";
String clientSecretSaml = "mockClientSecretmockClientSecretmockClientSecret";
+
+ Scope scope = Scope.parse("openid profile email");
@Autowired
@Qualifier("shibboleth.StorageService")
@@ -87,13 +89,13 @@ public class RevocationFlowTest extends AbstractOidcClientAuthenticationFlowTest
setBasicAuth(clientId, clientSecret);
setHttpFormRequest("POST", Collections.singletonMap("token", super.buildToken(clientId, "sub",
Scope.parse("openid")).toJSONObject().getAsString("access_token")));
- storeMetadata(storageService, clientId, clientSecret);
+ storeMetadata(storageService, clientId, clientSecret, scope);
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
parseSuccessResponse(result, OAuth2RevocationSuccessResponse.class);
}
@Test
- public void testSuccessWithSamlMetadata() throws IOException, NoSuchAlgorithmException, URISyntaxException,
+ public void testSuccessWithSamlMetadata() throws NoSuchAlgorithmException, URISyntaxException,
DataSealerException, ComponentInitializationException {
setBasicAuth(clientIdSaml, clientSecretSaml);
setHttpFormRequest("POST", Collections.singletonMap("token", super.buildToken(clientIdSaml, "sub",
@@ -108,7 +110,7 @@ public class RevocationFlowTest extends AbstractOidcClientAuthenticationFlowTest
setBasicAuth(clientId, clientSecret);
setHttpFormRequest("POST", Collections.singletonMap("token", super.buildLegacyToken(clientId, "sub",
Scope.parse("openid")).toJSONObject().getAsString("access_token")));
- storeMetadata(storageService, clientId, clientSecret);
+ storeMetadata(storageService, clientId, clientSecret, scope);
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
parseSuccessResponse(result, OAuth2RevocationSuccessResponse.class);
}
@@ -119,7 +121,7 @@ public class RevocationFlowTest extends AbstractOidcClientAuthenticationFlowTest
setBasicAuth(clientId, clientSecret);
setHttpFormRequest("POST", Collections.singletonMap("token", super.buildLegacyToken(clientId, "sub",
Scope.parse("openid"), "mail").toJSONObject().getAsString("access_token")));
- storeMetadata(storageService, clientId, clientSecret);
+ storeMetadata(storageService, clientId, clientSecret, scope);
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
parseSuccessResponse(result, OAuth2RevocationSuccessResponse.class);
}
@@ -127,12 +129,13 @@ public class RevocationFlowTest extends AbstractOidcClientAuthenticationFlowTest
protected FlowExecutionResult launchWithJwtAuthentication(final SignedJWT jwt, final JWSAlgorithm algorithm,
final ClientAuthenticationMethod method) throws Exception {
if (ClientAuthenticationMethod.CLIENT_SECRET_JWT.equals(method)) {
- storeMetadata(storageService, clientId, clientSecret, algorithm, method);
+ storeMetadata(storageService, clientId, clientSecret, scope, algorithm, method);
} else {
- storeMetadata(storageService, clientId, null, algorithm, method, null, rsaPublicKey);
+ storeMetadata(storageService, clientId, null, scope, algorithm, method, null, rsaPublicKey);
}
- final String accessToken = super.buildToken(clientId, "sub", Scope.parse("openid")).toJSONObject().getAsString("access_token");
- Map<String, String> requestParameters = new HashMap<>();
+ final String accessToken =
+ super.buildToken(clientId, "sub", Scope.parse("openid")).toJSONObject().getAsString("access_token");
+ final Map<String,String> requestParameters = new HashMap<>();
requestParameters.put("token", accessToken);
populateClientAssertionParams(requestParameters, jwt);
setHttpFormRequest("POST", requestParameters);
@@ -150,7 +153,7 @@ public class RevocationFlowTest extends AbstractOidcClientAuthenticationFlowTest
setBasicAuth(clientId, clientSecret + "X");
setHttpFormRequest("POST", Collections.singletonMap("token", super.buildLegacyToken(clientId, "sub",
Scope.parse("openid"), "mail").toJSONObject().getAsString("access_token")));
- storeMetadata(storageService, clientId, clientSecret);
+ storeMetadata(storageService, clientId, clientSecret, scope);
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertErrorCode(result, OAuth2Error.INVALID_CLIENT_CODE);
}
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java
index 677ff1dd..2e2127d9 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/TokenFlowTest.java
@@ -70,6 +70,8 @@ public class TokenFlowTest extends AbstractOidcClientAuthenticationFlowTest {
String clientIdPkcePlainUnforced = "mockClientIdPKCEPlainUnforced";
String clientIdPkceS256 = "mockClientIdPKCES256";
String codeVerifier = "9234567812345678123456781234567812345678123456781234567812345678";
+
+ Scope scope = Scope.parse("openid profile email");
@Autowired
@Qualifier("shibboleth.StorageService")
@@ -112,7 +114,7 @@ public class TokenFlowTest extends AbstractOidcClientAuthenticationFlowTest {
@Test
public void testUnauthorized() throws IOException, ParseException {
setHttpFormRequest("POST", createRequestParameters(redirectUri, "authorization_code", "mockCode", clientId));
- storeMetadata(storageService, clientId, clientSecret);
+ storeMetadata(storageService, clientId, clientSecret, scope);
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertErrorCode(result, OAuth2Error.INVALID_CLIENT_CODE);
}
@@ -120,19 +122,36 @@ public class TokenFlowTest extends AbstractOidcClientAuthenticationFlowTest {
@Test
public void testInvalidGrant() throws ParseException, IOException {
setHttpFormRequest("POST", createRequestParameters(redirectUri, "authorization_code", "mockCode", clientId));
- storeMetadata(storageService, clientId, clientSecret);
+ storeMetadata(storageService, clientId, clientSecret, scope);
setBasicAuth(clientId, clientSecret);
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
assertErrorCode(result, OAuth2Error.INVALID_GRANT_CODE);
}
+
+ @Test
+ public void testNoScopes() throws Exception {
+ // TODO: This test should probably be failing. The absence of scopes should prevent an id_token from
+ // being issued, but isn't. The sub claim is there via the authorization code even if it isn't
+ // "released" by the filter policy.
+ setHttpFormRequest("POST",
+ createRequestParameters(redirectUri, "authorization_code",
+ buildAuthorizationCode(clientId), clientId));
+ storeMetadata(storageService, clientId, clientSecret, null);
+ setBasicAuth(clientId, clientSecret);
+ storeConsent(storageService, "jdoe", clientId, "mail");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final OIDCTokenResponse response = parseSuccessResponse(result, OIDCTokenResponse.class);
+ Assert.assertNotNull(response.getTokens().getAccessToken());
+ Assert.assertNotNull(response.getOIDCTokens().getIDToken());
+ }
protected void initializeGrantAndRequest(final String clientId, final Map<String, String> requestParameters)
throws IOException {
setHttpFormRequest("POST", requestParameters);
- storeMetadata(storageService, clientId, clientSecret);
+ storeMetadata(storageService, clientId, clientSecret, scope);
setBasicAuth(clientId, clientSecret);
}
-
+
@Test
public void testValidGrant() throws Exception {
initializeGrantAndRequest(clientId, createRequestParameters(redirectUri, "authorization_code",
@@ -143,6 +162,26 @@ public class TokenFlowTest extends AbstractOidcClientAuthenticationFlowTest {
Assert.assertNotNull(response.getTokens().getAccessToken());
Assert.assertNotNull(response.getOIDCTokens().getIDToken());
}
+
+ @Test
+ public void testValidGrantWithRequestedScope() throws Exception {
+ final Map<String,String> params = createRequestParameters(redirectUri, "authorization_code",
+ buildAuthorizationCode(clientId), clientId);
+ params.put("scope", "openid profile");
+ initializeGrantAndRequest(clientId, params);
+ storeConsent(storageService, "jdoe", clientId, "mail");
+ final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
+ final OIDCTokenResponse response = parseSuccessResponse(result, OIDCTokenResponse.class);
+ Assert.assertNotNull(response.getTokens().getAccessToken());
+ Assert.assertNotNull(response.getOIDCTokens().getIDToken());
+
+ final ValidateGrantTest test = new ValidateGrantTest();
+ final AccessTokenClaimsSet token =
+ AccessTokenClaimsSet.parse(response.getTokens().getAccessToken().getValue(), test.getDataSealer());
+ Assert.assertTrue(token.getScope().contains("openid"));
+ Assert.assertTrue(token.getScope().contains("profile"));
+ Assert.assertFalse(token.getScope().contains("email"));
+ }
@Test
public void testValidLegacyGrant() throws Exception {
@@ -431,7 +470,7 @@ public class TokenFlowTest extends AbstractOidcClientAuthenticationFlowTest {
throws Exception {
final String code = ValidateGrantTest.buildAuthorizationCode(clientId, "https://op.example.org", "jdoe", "mock",
redirectUri).toString();
- storeMetadata(storageService, clientId, clientSecret, JWSAlgorithm.HS256,
+ storeMetadata(storageService, clientId, clientSecret, scope, JWSAlgorithm.HS256,
ClientAuthenticationMethod.CLIENT_SECRET_JWT);
final Map<String, String> requestParameters =
createRequestParameters(redirectUri, "authorization_code", code, clientId);
@@ -445,9 +484,9 @@ public class TokenFlowTest extends AbstractOidcClientAuthenticationFlowTest {
final String code = ValidateGrantTest.buildAuthorizationCode(clientId, "https://op.example.org", "jdoe", "mock",
redirectUri).toString();
if (ClientAuthenticationMethod.CLIENT_SECRET_JWT.equals(method)) {
- storeMetadata(storageService, clientId, clientSecret, algorithm, method);
+ storeMetadata(storageService, clientId, clientSecret, scope, algorithm, method);
} else {
- storeMetadata(storageService, clientId, null, algorithm, method, null, rsaPublicKey);
+ storeMetadata(storageService, clientId, null, scope, algorithm, method, null, rsaPublicKey);
}
final Map<String, String> requestParameters =
createRequestParameters(redirectUri, "authorization_code", code, clientId);
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/UserInfoTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/UserInfoTest.java
index 2e61fad6..41dc6206 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/UserInfoTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/flow/UserInfoTest.java
@@ -54,6 +54,8 @@ public class UserInfoTest extends AbstractOidcApiFlowTest {
String clientId = "mockClientId";
String clientIdSaml = "mockSamlClientId";
String subject = "mockSubject";
+
+ Scope scope = Scope.parse("openid profile email");
@Autowired
@Qualifier("shibboleth.StorageService")
@@ -96,7 +98,7 @@ public class UserInfoTest extends AbstractOidcApiFlowTest {
public void testSuccessOnlySubject() throws URISyntaxException, NoSuchAlgorithmException, DataSealerException,
ComponentInitializationException, IOException {
final BearerAccessToken token = buildToken(clientId, subject, new Scope("openid"));
- storeMetadata(storageService, clientId, "mockSecret");
+ storeMetadata(storageService, clientId, "mockSecret", scope);
request.addHeader("Authorization", token.toAuthorizationHeader());
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
final UserInfoSuccessResponse response = parseSuccessResponse(result, UserInfoSuccessResponse.class);
@@ -112,7 +114,7 @@ public class UserInfoTest extends AbstractOidcApiFlowTest {
public void testSuccessOnlySubjectWithLegacyToken() throws URISyntaxException, NoSuchAlgorithmException, DataSealerException,
ComponentInitializationException, IOException, com.nimbusds.oauth2.sdk.ParseException {
final BearerAccessToken token = buildLegacyToken(clientId, subject, new Scope("openid"));
- storeMetadata(storageService, clientId, "mockSecret");
+ storeMetadata(storageService, clientId, "mockSecret", scope);
request.addHeader("Authorization", token.toAuthorizationHeader());
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
final UserInfoSuccessResponse response = parseSuccessResponse(result, UserInfoSuccessResponse.class);
@@ -144,7 +146,7 @@ public class UserInfoTest extends AbstractOidcApiFlowTest {
public void testSuccessEmailResolution() throws URISyntaxException, NoSuchAlgorithmException, DataSealerException,
ComponentInitializationException, IOException {
final BearerAccessToken token = buildToken(clientId, subject, new Scope("openid", "email", "profile"));
- storeMetadata(storageService, clientId, "mockSecret");
+ storeMetadata(storageService, clientId, "mockSecret", scope);
storeConsent(storageService, "jdoe", clientId, "mail");
request.addHeader("Authorization", token.toAuthorizationHeader());
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
@@ -161,7 +163,7 @@ public class UserInfoTest extends AbstractOidcApiFlowTest {
public void testSuccessEmailResolutionWithLegacyToken() throws URISyntaxException, NoSuchAlgorithmException,
DataSealerException, ComponentInitializationException, IOException, com.nimbusds.oauth2.sdk.ParseException {
final BearerAccessToken token = buildLegacyToken(clientId, subject, new Scope("openid", "email", "profile"));
- storeMetadata(storageService, clientId, "mockSecret");
+ storeMetadata(storageService, clientId, "mockSecret", scope);
storeConsent(storageService, "jdoe", clientId, "mail");
request.addHeader("Authorization", token.toAuthorizationHeader());
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
@@ -179,7 +181,7 @@ public class UserInfoTest extends AbstractOidcApiFlowTest {
DataSealerException, ComponentInitializationException, IOException, com.nimbusds.oauth2.sdk.ParseException {
final BearerAccessToken token = buildLegacyToken(clientId, subject, new Scope("openid", "email", "profile"),
"mail");
- storeMetadata(storageService, clientId, "mockSecret");
+ storeMetadata(storageService, clientId, "mockSecret", scope);
storeConsent(storageService, "jdoe", clientId, "mail");
request.addHeader("Authorization", token.toAuthorizationHeader());
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
@@ -198,7 +200,7 @@ public class UserInfoTest extends AbstractOidcApiFlowTest {
com.nimbusds.oauth2.sdk.ParseException {
final BearerAccessToken token = buildLegacyToken(clientId, subject, new Scope("openid", "email", "profile"),
"not_mail");
- storeMetadata(storageService, clientId, "mockSecret");
+ storeMetadata(storageService, clientId, "mockSecret", scope);
storeConsent(storageService, "jdoe", clientId, "mail");
request.addHeader("Authorization", token.toAuthorizationHeader());
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
@@ -217,7 +219,7 @@ public class UserInfoTest extends AbstractOidcApiFlowTest {
final TokenDeliveryClaimsClaimsSet set = new TokenDeliveryClaimsClaimsSet();
set.setClaim("nickname", "mockNickname");
final BearerAccessToken token = buildToken(clientId, subject, new Scope("openid", "profile"), set);
- storeMetadata(storageService, clientId, "mockSecret");
+ storeMetadata(storageService, clientId, "mockSecret", scope);
request.addHeader("Authorization", token.toAuthorizationHeader());
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
final UserInfoSuccessResponse response = parseSuccessResponse(result, UserInfoSuccessResponse.class);
@@ -233,8 +235,8 @@ public class UserInfoTest extends AbstractOidcApiFlowTest {
public void testSuccessEmailResolutionAndIssuerWithSignedResponse() throws URISyntaxException,
NoSuchAlgorithmException, DataSealerException, ComponentInitializationException, IOException, ParseException {
final BearerAccessToken token = buildToken(clientId, subject, new Scope("openid", "email", "profile"));
- storeMetadata(storageService, clientId, "mockSecret", null, ClientAuthenticationMethod.CLIENT_SECRET_BASIC,
- JWSAlgorithm.RS256);
+ storeMetadata(storageService, clientId, "mockSecret", scope, null,
+ ClientAuthenticationMethod.CLIENT_SECRET_BASIC, JWSAlgorithm.RS256);
storeConsent(storageService, "jdoe", clientId, "mail");
request.addHeader("Authorization", token.toAuthorizationHeader());
final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/BaseOIDCResponseActionTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/BaseOIDCResponseActionTest.java
index a84600b6..15cb4612 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/BaseOIDCResponseActionTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/BaseOIDCResponseActionTest.java
@@ -198,7 +198,7 @@ public abstract class BaseOIDCResponseActionTest {
respCtx.setProcessedToken(jwt);
}
- protected DataSealer getDataSealer() throws ComponentInitializationException, NoSuchAlgorithmException {
+ public DataSealer getDataSealer() throws ComponentInitializationException, NoSuchAlgorithmException {
if (dataSealer == null) {
dataSealer = initializeDataSealer();
}
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/SetSubjectToResponseContextTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/SetSubjectToResponseContextTest.java
index 4cdef58e..1ca8c150 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/SetSubjectToResponseContextTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/SetSubjectToResponseContextTest.java
@@ -17,6 +17,7 @@
package net.shibboleth.idp.plugin.oidc.op.profile.impl;
+import net.shibboleth.idp.plugin.oidc.op.profile.OidcEventIds;
import net.shibboleth.idp.plugin.oidc.op.profile.context.navigate.TokenRequestSubjectLookupFunction;
import net.shibboleth.idp.plugin.oidc.op.token.support.AccessTokenClaimsSet;
import net.shibboleth.idp.plugin.oidc.op.token.support.TokenClaimsSet;
@@ -29,7 +30,6 @@ import java.net.URISyntaxException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
-import org.opensaml.profile.action.EventIds;
import org.springframework.webflow.execution.Event;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -53,7 +53,7 @@ public class SetSubjectToResponseContextTest extends BaseOIDCResponseActionTest
public void testNoSubject() throws ComponentInitializationException {
init();
final Event event = action.execute(requestCtx);
- ActionTestingSupport.assertEvent(event, EventIds.INVALID_PROFILE_CTX);
+ ActionTestingSupport.assertEvent(event, OidcEventIds.INVALID_SUBJECT);
}
/**
diff --git a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateScopeTest.java b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateScopeTest.java
index cd041d40..29d23edc 100644
--- a/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateScopeTest.java
+++ b/idp-oidc-extension-impl/src/test/java/net/shibboleth/idp/plugin/oidc/op/profile/impl/ValidateScopeTest.java
@@ -85,7 +85,9 @@ public class ValidateScopeTest extends BaseOIDCResponseActionTest {
}
/**
- * Test that action filters out non valid scopes on front-channel.
+ * Test that action filters out non valid scopes during an Authentication request.
+ *
+ * <p>The message here is created by the base class's setup method.</p>
*
* @throws ComponentInitializationException
*/
@@ -95,14 +97,16 @@ public class ValidateScopeTest extends BaseOIDCResponseActionTest {
ActionTestingSupport.assertProceedEvent(event);
// input is openid, profile, offline_access and email. profile and offline_access should be filtered out
// (offline because the request is implicit).
+ Assert.assertNotNull(respCtx.getScope());
Assert.assertTrue(respCtx.getScope().contains(OIDCScopeValue.OPENID));
Assert.assertTrue(respCtx.getScope().contains(OIDCScopeValue.EMAIL));
Assert.assertFalse(respCtx.getScope().contains(OIDCScopeValue.OFFLINE_ACCESS));
Assert.assertFalse(respCtx.getScope().contains(OIDCScopeValue.PROFILE));
}
-
+
/**
- * Test that action copes if there are no registered scopes.
+ * Test that action copes if there are no registered scopes in the metadata during an
+ * Authentication request.
*
* @throws ComponentInitializationException
*/
@@ -120,6 +124,8 @@ public class ValidateScopeTest extends BaseOIDCResponseActionTest {
/**
* Test that action filters out unregistered scopes on back-channel with no prior grant.
*
+ * <p>This is most common for the client_credentials grant, which has no prior step.</p>
+ *
* @throws ComponentInitializationException
* @throws URISyntaxException
*/
@@ -152,6 +158,8 @@ public class ValidateScopeTest extends BaseOIDCResponseActionTest {
/**
* Test that action filters out unregistered scopes on back-channel with prior grant of nothing.
*
+ * <p>This is likely impossible in practice, but theoretical.</p>
+ *
* @throws ComponentInitializationException
* @throws URISyntaxException
*/
@@ -224,6 +232,8 @@ public class ValidateScopeTest extends BaseOIDCResponseActionTest {
/**
* Test that action filters out unregistered scopes on UserInfo with prior grants.
*
+ * <p>Exercises case with prior grants but nothing requested.</p>
+ *
* @throws ComponentInitializationException
* @throws URISyntaxException
*/
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list