mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
[OID4VCI] Fix deprecated realm-scoped well-known endpoint access
Signed-off-by: Thomas Diesler <tdiesler@ibm.com>
This commit is contained in:
parent
ebd4a6936a
commit
39264edf3f
@ -303,7 +303,7 @@ function RealmSettingsGeneralTabForm({
|
||||
<FormattedLink
|
||||
href={`${addTrailingSlash(
|
||||
serverBaseUrl,
|
||||
)}realms/${realmName}/.well-known/openid-credential-issuer`}
|
||||
)}.well-known/openid-credential-issuer/realms/${realmName}`}
|
||||
title={t("oid4vcIssuerMetadata")}
|
||||
/>
|
||||
</StackItem>
|
||||
|
||||
@ -17,13 +17,18 @@
|
||||
|
||||
package org.keycloak.protocol.oid4vc.model;
|
||||
|
||||
import java.beans.Transient;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.keycloak.common.util.KeycloakUriBuilder;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import static org.keycloak.OID4VCConstants.WELL_KNOWN_OPENID_CREDENTIAL_ISSUER;
|
||||
|
||||
/**
|
||||
* Represents a CredentialsOffer according to the OID4VCI Spec
|
||||
* {@see https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html#name-credential-offer}
|
||||
@ -52,6 +57,23 @@ public class CredentialsOffer {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Transient
|
||||
public String getIssuerMetadataUrl() {
|
||||
var metadataUrl = KeycloakUriBuilder
|
||||
.fromUri(credentialIssuer)
|
||||
.path("/.well-known/" + WELL_KNOWN_OPENID_CREDENTIAL_ISSUER);
|
||||
var idx = credentialIssuer.indexOf("/realms");
|
||||
if (idx > 0) {
|
||||
var baseUrl = credentialIssuer.substring(0, idx);
|
||||
var realmPath = credentialIssuer.substring(idx);
|
||||
metadataUrl = KeycloakUriBuilder
|
||||
.fromUri(baseUrl)
|
||||
.path("/.well-known/" + WELL_KNOWN_OPENID_CREDENTIAL_ISSUER)
|
||||
.path(realmPath);
|
||||
}
|
||||
return metadataUrl.buildAsString();
|
||||
}
|
||||
|
||||
public List<String> getCredentialConfigurationIds() {
|
||||
return credentialConfigurationIds;
|
||||
}
|
||||
|
||||
@ -96,7 +96,7 @@ public abstract class OID4VCAuthorizationCodeFlowTestBase extends OID4VCIssuerEn
|
||||
Oid4vcTestContext ctx = new Oid4vcTestContext();
|
||||
|
||||
// Get credential issuer metadata
|
||||
HttpGet getCredentialIssuer = new HttpGet(getRealmPath(TEST_REALM_NAME) + "/.well-known/openid-credential-issuer");
|
||||
HttpGet getCredentialIssuer = new HttpGet(getRealmMetadataPath(TEST_REALM_NAME));
|
||||
try (CloseableHttpResponse response = httpClient.execute(getCredentialIssuer)) {
|
||||
assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
|
||||
String s = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
||||
@ -99,7 +99,7 @@ public class OID4VCAuthorizationCodeFlowWithPARTest extends OID4VCIssuerEndpoint
|
||||
Oid4vcTestContext ctx = new Oid4vcTestContext();
|
||||
|
||||
// Get credential issuer metadata
|
||||
HttpGet getCredentialIssuer = new HttpGet(getRealmPath(TEST_REALM_NAME) + "/.well-known/openid-credential-issuer");
|
||||
HttpGet getCredentialIssuer = new HttpGet(getRealmMetadataPath(TEST_REALM_NAME));
|
||||
try (CloseableHttpResponse response = httpClient.execute(getCredentialIssuer)) {
|
||||
assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
|
||||
String s = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
||||
@ -121,7 +121,7 @@ public abstract class OID4VCAuthorizationDetailsFlowTestBase extends OID4VCIssue
|
||||
ctx.credentialsOffer = JsonSerialization.readValue(s, CredentialsOffer.class);
|
||||
}
|
||||
|
||||
HttpGet getIssuerMetadata = new HttpGet(ctx.credentialsOffer.getCredentialIssuer() + "/.well-known/openid-credential-issuer");
|
||||
HttpGet getIssuerMetadata = new HttpGet(ctx.credentialsOffer.getIssuerMetadataUrl());
|
||||
try (CloseableHttpResponse response = httpClient.execute(getIssuerMetadata)) {
|
||||
assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
|
||||
String s = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
||||
@ -68,7 +68,6 @@ import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.oid4vci.CredentialScopeModel;
|
||||
import org.keycloak.protocol.oid4vc.issuance.OID4VCAuthorizationDetailsResponse;
|
||||
import org.keycloak.protocol.oid4vc.issuance.OID4VCIssuerEndpoint;
|
||||
import org.keycloak.protocol.oid4vc.issuance.OID4VCIssuerWellKnownProviderFactory;
|
||||
import org.keycloak.protocol.oid4vc.issuance.TimeProvider;
|
||||
import org.keycloak.protocol.oid4vc.issuance.credentialbuilder.CredentialBuilder;
|
||||
import org.keycloak.protocol.oid4vc.issuance.credentialbuilder.JwtCredentialBuilder;
|
||||
@ -92,12 +91,10 @@ import org.keycloak.representations.idm.RoleRepresentation;
|
||||
import org.keycloak.representations.idm.UserRepresentation;
|
||||
import org.keycloak.services.managers.AppAuthManager;
|
||||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
import org.keycloak.testsuite.Assert;
|
||||
import org.keycloak.testsuite.admin.ApiUtil;
|
||||
import org.keycloak.testsuite.runonserver.RunOnServerException;
|
||||
import org.keycloak.testsuite.util.AdminClientUtil;
|
||||
import org.keycloak.testsuite.util.oauth.OAuthClient;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
@ -473,11 +470,8 @@ public abstract class OID4VCIssuerEndpointTest extends OID4VCTest {
|
||||
String testCredentialConfigurationId = clientScope.getAttributes().get(CredentialScopeModel.CONFIGURATION_ID);
|
||||
|
||||
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);
|
||||
String metadataUrl = getRealmMetadataPath(TEST_REALM_NAME);
|
||||
WebTarget oid4vciDiscoveryTarget = client.target(metadataUrl);
|
||||
|
||||
// 1. Get authoriZation code without scope specified by wallet
|
||||
// 2. Using the code to get accesstoken
|
||||
@ -528,7 +522,13 @@ public abstract class OID4VCIssuerEndpointTest extends OID4VCTest {
|
||||
}
|
||||
|
||||
protected String getRealmPath(String realm) {
|
||||
return suiteContext.getAuthServerInfo().getContextRoot().toString() + "/auth/realms/" + realm;
|
||||
return suiteContext.getAuthServerInfo().getContextRoot() + "/auth/realms/" + realm;
|
||||
}
|
||||
|
||||
protected String getRealmMetadataPath(String realm) {
|
||||
var contextRoot = suiteContext.getAuthServerInfo().getContextRoot();
|
||||
// [TODO] This should be contextRoot/.well-known/openid-credential-issuer/auth/realms/...
|
||||
return contextRoot + "/auth/.well-known/openid-credential-issuer/realms/" + realm;
|
||||
}
|
||||
|
||||
protected void requestCredential(String token,
|
||||
@ -558,7 +558,7 @@ public abstract class OID4VCIssuerEndpointTest extends OID4VCTest {
|
||||
}
|
||||
|
||||
public CredentialIssuer getCredentialIssuerMetadata() {
|
||||
final String endpoint = getRealmPath(TEST_REALM_NAME) + "/.well-known/openid-credential-issuer";
|
||||
final String endpoint = getRealmMetadataPath(TEST_REALM_NAME);
|
||||
HttpGet getMetadataRequest = new HttpGet(endpoint);
|
||||
try (CloseableHttpResponse metadataResponse = httpClient.execute(getMetadataRequest)) {
|
||||
assertEquals(HttpStatus.SC_OK, metadataResponse.getStatusLine().getStatusCode());
|
||||
|
||||
@ -19,7 +19,6 @@ package org.keycloak.testsuite.oid4vc.issuance.signing;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -31,7 +30,6 @@ import java.util.Optional;
|
||||
import jakarta.ws.rs.client.Client;
|
||||
import jakarta.ws.rs.client.WebTarget;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.UriBuilder;
|
||||
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.common.util.Time;
|
||||
@ -52,7 +50,6 @@ import org.keycloak.protocol.ProtocolMapper;
|
||||
import org.keycloak.protocol.oid4vc.OID4VCLoginProtocolFactory;
|
||||
import org.keycloak.protocol.oid4vc.issuance.OID4VCIssuerEndpoint;
|
||||
import org.keycloak.protocol.oid4vc.issuance.OID4VCIssuerWellKnownProvider;
|
||||
import org.keycloak.protocol.oid4vc.issuance.OID4VCIssuerWellKnownProviderFactory;
|
||||
import org.keycloak.protocol.oid4vc.issuance.mappers.OID4VCMapper;
|
||||
import org.keycloak.protocol.oid4vc.model.Claim;
|
||||
import org.keycloak.protocol.oid4vc.model.ClaimDisplay;
|
||||
@ -68,7 +65,6 @@ import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.ClientScopeRepresentation;
|
||||
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.services.resources.RealmsResource;
|
||||
import org.keycloak.testsuite.arquillian.SuiteContext;
|
||||
import org.keycloak.testsuite.client.KeycloakTestingClient;
|
||||
import org.keycloak.testsuite.util.AdminClientUtil;
|
||||
@ -133,7 +129,7 @@ public class OID4VCIssuerWellKnownProviderTest extends OID4VCIssuerEndpointTest
|
||||
@Test
|
||||
public void testUnsignedMetadata() {
|
||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
|
||||
String wellKnownUri = OAuthClient.AUTH_SERVER_ROOT + "/realms/" + TEST_REALM_NAME + "/.well-known/openid-credential-issuer";
|
||||
String wellKnownUri = getRealmMetadataPath(TEST_REALM_NAME);
|
||||
String expectedIssuer = getRealmPath(TEST_REALM_NAME);
|
||||
|
||||
// Configure realm for unsigned metadata
|
||||
@ -173,7 +169,7 @@ public class OID4VCIssuerWellKnownProviderTest extends OID4VCIssuerEndpointTest
|
||||
@Test
|
||||
public void testSignedMetadata() {
|
||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
|
||||
String wellKnownUri = OAuthClient.AUTH_SERVER_ROOT + "/realms/" + TEST_REALM_NAME + "/.well-known/openid-credential-issuer";
|
||||
String wellKnownUri = getRealmMetadataPath(TEST_REALM_NAME);
|
||||
String expectedIssuer = getRealmPath(TEST_REALM_NAME);
|
||||
|
||||
// Configure realm for signed metadata
|
||||
@ -249,7 +245,7 @@ public class OID4VCIssuerWellKnownProviderTest extends OID4VCIssuerEndpointTest
|
||||
@Test
|
||||
public void testUnsignedMetadataWhenSignedDisabled() {
|
||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
|
||||
String wellKnownUri = OAuthClient.AUTH_SERVER_ROOT + "/realms/" + TEST_REALM_NAME + "/.well-known/openid-credential-issuer";
|
||||
String wellKnownUri = getRealmMetadataPath(TEST_REALM_NAME);
|
||||
String expectedIssuer = getRealmPath(TEST_REALM_NAME);
|
||||
|
||||
// Disable signed metadata
|
||||
@ -279,7 +275,7 @@ public class OID4VCIssuerWellKnownProviderTest extends OID4VCIssuerEndpointTest
|
||||
@Test
|
||||
public void testSignedMetadataWithInvalidLifespan() {
|
||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
|
||||
String wellKnownUri = OAuthClient.AUTH_SERVER_ROOT + "/realms/" + TEST_REALM_NAME + "/.well-known/openid-credential-issuer";
|
||||
String wellKnownUri = getRealmMetadataPath(TEST_REALM_NAME);
|
||||
String expectedIssuer = getRealmPath(TEST_REALM_NAME);
|
||||
|
||||
// Configure invalid lifespan
|
||||
@ -309,7 +305,7 @@ public class OID4VCIssuerWellKnownProviderTest extends OID4VCIssuerEndpointTest
|
||||
@Test
|
||||
public void testSignedMetadataWithInvalidAlgorithm() {
|
||||
try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) {
|
||||
String wellKnownUri = OAuthClient.AUTH_SERVER_ROOT + "/realms/" + TEST_REALM_NAME + "/.well-known/openid-credential-issuer";
|
||||
String wellKnownUri = getRealmMetadataPath(TEST_REALM_NAME);
|
||||
String expectedIssuer = getRealmPath(TEST_REALM_NAME);
|
||||
|
||||
// Configure invalid algorithm
|
||||
@ -456,10 +452,8 @@ public class OID4VCIssuerWellKnownProviderTest extends OID4VCIssuerEndpointTest
|
||||
@Test
|
||||
public void testIssuerMetadataIncludesEncryptionSupport() throws IOException {
|
||||
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);
|
||||
String wellKnownUri = getRealmMetadataPath(TEST_REALM_NAME);
|
||||
WebTarget oid4vciDiscoveryTarget = client.target(wellKnownUri);
|
||||
|
||||
try (Response discoveryResponse = oid4vciDiscoveryTarget.request().get()) {
|
||||
CredentialIssuer oid4vciIssuerConfig = JsonSerialization.readValue(
|
||||
|
||||
@ -451,7 +451,7 @@ public class OID4VCJWTIssuerEndpointTest extends OID4VCIssuerEndpointTest {
|
||||
CredentialsOffer credentialsOffer = JsonSerialization.readValue(s, CredentialsOffer.class);
|
||||
|
||||
// 3. Get the issuer metadata
|
||||
HttpGet getIssuerMetadata = new HttpGet(credentialsOffer.getCredentialIssuer() + "/.well-known/openid-credential-issuer");
|
||||
HttpGet getIssuerMetadata = new HttpGet(credentialsOffer.getIssuerMetadataUrl());
|
||||
CloseableHttpResponse issuerMetadataResponse = httpClient.execute(getIssuerMetadata);
|
||||
assertEquals(HttpStatus.SC_OK, issuerMetadataResponse.getStatusLine().getStatusCode());
|
||||
s = IOUtils.toString(issuerMetadataResponse.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
||||
@ -323,7 +323,7 @@ public class OID4VCSdJwtIssuingEndpointTest extends OID4VCIssuerEndpointTest {
|
||||
CredentialsOffer credentialsOffer = JsonSerialization.readValue(s, CredentialsOffer.class);
|
||||
|
||||
// 3. Get the issuer metadata
|
||||
HttpGet getIssuerMetadata = new HttpGet(credentialsOffer.getCredentialIssuer() + "/.well-known/openid-credential-issuer");
|
||||
HttpGet getIssuerMetadata = new HttpGet(credentialsOffer.getIssuerMetadataUrl());
|
||||
CloseableHttpResponse issuerMetadataResponse = httpClient.execute(getIssuerMetadata);
|
||||
assertEquals(HttpStatus.SC_OK, issuerMetadataResponse.getStatusLine().getStatusCode());
|
||||
s = IOUtils.toString(issuerMetadataResponse.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user