Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
Signed-off-by: Takashi Norimatsu <[email protected]>
  • Loading branch information
tnorimat committed Jun 14, 2024
1 parent a34f3a1 commit f800a41
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,10 @@ private void checkScope(CredentialRequest credentialRequestVO) {
if (vcIssuanceFlow == null || !vcIssuanceFlow.equals(PreAuthorizedCodeGrantTypeFactory.GRANT_TYPE)) {
// authz code flow
ClientModel client = clientSession.getClient();
client.getAttributes().forEach((i,j)->System.out.println("GGGGGGGGGG OID4VCIssuerEndpoint : key = " + i + " value = " + j));
String credentialIdentifier = credentialRequestVO.getCredentialIdentifier();
String scope = client.getAttributes().get(credentialIdentifier);
String scope = client.getAttributes().get("vc." + credentialIdentifier + ".scope");
System.out.println("GGGGGGGGGG OID4VCIssuerEndpoint : checkScope : credentialIdentifier = " + credentialIdentifier + " scope = " + scope);
AccessToken accessToken = bearerTokenAuthenticator.authenticate().getToken();
if (Arrays.stream(accessToken.getScope().split(" ")).sequential().noneMatch(i->i.equals(scope))) {
LOGGER.debugf("Scope check failure: credentialIdentifier = %s, required scope = %s, scope in access token = %s.", credentialIdentifier, scope, accessToken.getScope());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@
import org.keycloak.protocol.oid4vc.model.CredentialRequest;
import org.keycloak.protocol.oid4vc.model.CredentialResponse;
import org.keycloak.protocol.oid4vc.model.CredentialsOffer;
import org.keycloak.protocol.oid4vc.model.ErrorResponse;
import org.keycloak.protocol.oid4vc.model.ErrorType;
import org.keycloak.protocol.oid4vc.model.Format;
import org.keycloak.protocol.oid4vc.model.OfferUriType;
import org.keycloak.protocol.oid4vc.model.PreAuthorizedGrant;
Expand Down Expand Up @@ -374,15 +372,6 @@ public void testRequestCredential() {
}));
}

public static ClientResource findClientByClientId(RealmResource realm, String clientId) {
for (ClientRepresentation c : realm.clients().findAll()) {
if (clientId.equals(c.getClientId())) {
return realm.clients().get(c.getId());
}
}
return null;
}

// Tests the complete flow from
// 1. Retrieving the credential-offer-uri
// 2. Using the uri to get the actual credential offer
Expand Down Expand Up @@ -457,27 +446,50 @@ public void testCredentialIssuance() throws Exception {
});
}

private ClientResource findClientByClientId(RealmResource realm, String clientId) {
for (ClientRepresentation c : realm.clients().findAll()) {
if (clientId.equals(c.getClientId())) {
return realm.clients().get(c.getId());
}
}
return null;
}

// Tests the AuthZCode complete flow without scope from
// 1. Get authorization code without scope specified by wallet
// 2. Using the code to get access token
// 3. Get the credential configuration id from issuer metadata at .wellKnown
// 4. With the access token, get the credential
@Test
public void testCredentialIssuanceWithAuthZCode() throws Exception {
private String registerOptionalClientScope(String scopeName) {
ClientScopeRepresentation clientScope = new ClientScopeRepresentation();
clientScope.setName("scope-test-credential");
clientScope.setName(scopeName);
clientScope.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
Response res = testRealm().clientScopes().create(clientScope);
String scopeId = ApiUtil.getCreatedId(res);
getCleanup().addClientScopeId(scopeId);
getCleanup().addClientScopeId(scopeId); // automatically removed when a test method is finished.
res.close();
return scopeId;
}

ClientResource clientResource = findClientByClientId(testRealm(), "test-app");
private void assignOptionalClientScopeToClient(String scopeId, String clientId) {
ClientResource clientResource = findClientByClientId(testRealm(), clientId);
ClientRepresentation clientRepresentation = clientResource.toRepresentation();
clientRepresentation.getAttributes().put("test-credential","scope-test-credential");
clientResource.update(clientRepresentation);
clientResource.addOptionalClientScope(scopeId);
}

// Tests the AuthZCode complete flow without scope from
// 1. Get authorization code without scope specified by wallet
// 2. Using the code to get access token
// 3. Get the credential configuration id from issuer metadata at .wellKnown
// 4. With the access token, get the credential
@Test
public void testCredentialIssuanceWithAuthZCodeWithScopeMatched() throws Exception {
// use pre-registered client for this test class whose clientId is "did:web:test.org" by OID4VCTest.getTestClient
// This client registered credential identifier named "test-credential"
// Its scope value is "VerifiableCredential"

// 1. register optional client scope
String scopeId = registerOptionalClientScope("VerifiableCredential");

// 2. assign registered optional client scope
assignOptionalClientScopeToClient(scopeId, "did:web:test.org"); // pre-registered client for this test class

try (Client client = AdminClientUtil.createResteasyClient()) {
UriBuilder builder = UriBuilder.fromUri(OAuthClient.AUTH_SERVER_ROOT);
Expand All @@ -486,7 +498,7 @@ public void testCredentialIssuanceWithAuthZCode() throws Exception {

// 1. Get authoriZation code without scope specified by wallet
// 2. Using the code to get accesstoken
String token = getBearerToken(oauth.openid(false).scope("scope-test-credential"));
String token = getBearerToken(oauth.clientId("did:web:test.org").openid(false).scope("VerifiableCredential"));

// 3. Get the credential configuration id from issuer metadata at .wellKnown
try (Response discoveryResponse = oid4vciDiscoveryTarget.request().get()) {
Expand Down Expand Up @@ -525,7 +537,7 @@ public void testCredentialIssuanceWithAuthZCode() throws Exception {
}

// clean-up
clientResource.removeOptionalClientScope(scopeId);
//clientResource.removeOptionalClientScope(scopeId);
}

// Tests the AuthZCode complete flow without scope from
Expand Down Expand Up @@ -589,6 +601,66 @@ public void testCredentialIssuanceWithAuthZCodeScopeUnmatched() throws Exception
clientResource.removeOptionalClientScope(scopeId);
}

// Tests the AuthZCode complete flow without scope from
// 1. Get authorization code without scope specified by wallet
// 2. Using the code to get access token
// 3. Get the credential configuration id from issuer metadata at .wellKnown
// 4. With the access token, get the credential
@Test
public void testCredentialIssuanceWithoutScope() throws Exception {
ClientScopeRepresentation clientScope = new ClientScopeRepresentation();
clientScope.setName("scope-test-credential");
clientScope.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
Response res = testRealm().clientScopes().create(clientScope);
String scopeId = ApiUtil.getCreatedId(res);
getCleanup().addClientScopeId(scopeId);
res.close();

ClientResource clientResource = findClientByClientId(testRealm(), "test-app");
ClientRepresentation clientRepresentation = clientResource.toRepresentation();
clientRepresentation.getAttributes().put("test-credential", "different-scope-test-credential");
clientResource.update(clientRepresentation);
clientResource.addOptionalClientScope(scopeId);

try (Client client = AdminClientUtil.createResteasyClient()) {
UriBuilder builder = UriBuilder.fromUri(OAuthClient.AUTH_SERVER_ROOT);
URI oid4vciDiscoveryUri = RealmsResource.wellKnownProviderUrl(builder).build(TEST_REALM_NAME, OID4VCIssuerWellKnownProviderFactory.PROVIDER_ID);
WebTarget oid4vciDiscoveryTarget = client.target(oid4vciDiscoveryUri);

// 1. Get authoriZation code without scope specified by wallet
// 2. Using the code to get accesstoken
String token = getBearerToken(oauth.openid(false).scope(null));

// 3. Get the credential configuration id from issuer metadata at .wellKnown
try (Response discoveryResponse = oid4vciDiscoveryTarget.request().get()) {
CredentialIssuer oid4vciIssuerConfig = JsonSerialization.readValue(discoveryResponse.readEntity(String.class), CredentialIssuer.class);
assertEquals(200, discoveryResponse.getStatus());
assertEquals(getRealmPath(TEST_REALM_NAME), oid4vciIssuerConfig.getCredentialIssuer());
assertEquals(getBasePath(TEST_REALM_NAME) + "credential", oid4vciIssuerConfig.getCredentialEndpoint());

// 4. With the access token, get the credential
try (Client clientForCredentialRequest = AdminClientUtil.createResteasyClient()) {
UriBuilder credentialUriBuilder = UriBuilder.fromUri(oid4vciIssuerConfig.getCredentialEndpoint());
URI credentialUri = credentialUriBuilder.build();
WebTarget credentialTarget = clientForCredentialRequest.target(credentialUri);

CredentialRequest request = new CredentialRequest();
request.setFormat(oid4vciIssuerConfig.getCredentialsSupported().get("test-credential").getFormat());
request.setCredentialIdentifier(oid4vciIssuerConfig.getCredentialsSupported().get("test-credential").getId());

assertEquals("jwt_vc", oid4vciIssuerConfig.getCredentialsSupported().get("test-credential").getFormat().toString());
assertEquals("test-credential", oid4vciIssuerConfig.getCredentialsSupported().get("test-credential").getId());

try (Response response = credentialTarget.request().header(HttpHeaders.AUTHORIZATION, "bearer " + token).post(Entity.json(request))) {
assertEquals(400, response.getStatus());
}
}
}
}

// clean-up
clientResource.removeOptionalClientScope(scopeId);
}

private static String prepareNonce(AppAuthManager.BearerTokenAuthenticator authenticator, String note) {
String nonce = SecretGenerator.getInstance().randomString();
Expand Down

0 comments on commit f800a41

Please sign in to comment.