Repository navigation
Compliant with RFC8414, return server metadata at /.well-known/oauth-authorization-server/realms/{realm} - #41440
Conversation
There was a problem hiding this comment.
Hello @tnorimat - I am jumping in because a very identical change is required by OpenID4VCI Draft 16 as we will need /.well-known/openid-credential-issuer/realms/{realm}.
Credential Issuers publishing metadata MUST make a JSON document available at the path formed inserting the string /.well-known/openid-credential-issuer into the Credential Issuer Identifier between the host component and the path component, if any.
For example, the metadata for the Credential Issuer Identifier https://issuer.example.com/tenant would be retrieved from https://issuer.example.com/.well-known/openid-credential-issuer/tenant. The metadata for the Credential Issuer Identifier https://tenant.issuer.example.com would be retrieved from https://tenant.issuer.example.com/.well-known/openid-credential-issuer.
Could this PR take into account extensibility regarding well-known resources in general? I mean something close to the suggestion of @thomasdarimont here: https://cloud-native.slack.com/archives/C05KR0TL4P8/p1752669894360769?thread_ts=1752669762.102799&cid=C05KR0TL4P8 ?
@Path(".well-known")
public class WellKnownRootResource {
protected static final Logger logger = Logger.getLogger(WellKnownRootResource.class);
@Context
protected KeycloakSession session;
@GET
@Path("/{providerId}/realms/{realmName}")
public Response getWellKnown(@PathParam("providerId") String providerId, @PathParam("realmName") String realmName) {
RealmModel realm = session.realms().getRealmByName(realmName);
if (realm == null) {
return Response.status(Response.Status.NOT_FOUND).build();
}
session.getContext().setRealm(realm);
WellKnownProvider knownProvider = session.getProvider(WellKnownProvider.class, providerId);
if (knownProvider == null) {
return Response.status(Response.Status.NOT_FOUND).build();
}
Object config = knownProvider.getConfig();
return Response.ok(config).build();
}
}There was a problem hiding this comment.
@IngridPuppet Hello, thank you for the feedback comment. I will incorporate the extensibility you suggested.
c6d1606 to
cb77869
Compare
|
@IngridPuppet I've revised the PR. Would it suit your purposes? |
There was a problem hiding this comment.
Thank you very much for updating the PR for extensibility. By adding IDs of WellKnownProvider's to the validProviderList array, we should have the correct endpoints automatically available. Additionally, I checked all the changes and agree with them.
ef87f1b to
0e9b967
Compare
|
@IngridPuppet I slightly modified the codes. OID4VCI is an experimental feature, so we need to consider that to publish OID4VCI'S metadata. |
There was a problem hiding this comment.
Do we need that Path("/") annotation here? Since it is the root entry point it might lead to conflicts with other resource handlers.
There was a problem hiding this comment.
@thomasdarimont Thank you for the comment. Yes, both root resource classes WelcomeResources and ServerMetadataResource have the same path annotation value /. To avoid this duplication, I modified as follows:
@Path("/.well-known")
public class ServerMetadataResource {
protected static final Logger logger = Logger.getLogger(ServerMetadataResource.class);
@Context
protected KeycloakSession session;
@OPTIONS
@Path("{provider}/realms/{realm}")
@Produces(MediaType.APPLICATION_JSON)
public Response getOAuth2AuthorizationServerWellKnownVersionPreflight(final @PathParam("provider") String providerName,
final @PathParam("realm") String name) {
if (!isValidProvider(providerName)) throw new NotFoundException();
return Cors.builder().allowedMethods("GET").preflight().auth().add(Response.ok());
}
@GET
@Path("{provider}/realms/{realm}")
@Produces(MediaType.APPLICATION_JSON)
public Response getOAuth2AuthorizationServerWellKnown(final @PathParam("provider") String providerName,
final @PathParam("realm") String name) {
if (!isValidProvider(providerName)) throw new NotFoundException();
return RealmsResource.getWellKnownResponse(session, name, providerName, logger);
}
…authorization-server/realms/{realm}
closes keycloak#40923
Signed-off-by: Takashi Norimatsu <takashi.norimatsu.ws@hitachi.com>
|
I just noticed that this only works as expected if Keycloak is configured with an empty context path. I don't know if it is possible to configure Keycloak to always listen on "/" for some requests despite the context path setting but if not we should document that users might need to use a reverse-proxy in front of Keycloak to route the The following nginx configuration works for me: |
|
@tnorimat @thomasdarimont @mposolda @stianst Would you be able to help this PR? Are there any significant concerns or blockers apart from the documentation? This PR is important for MCP and OID4VCI, and it is currently blocking the following issue: #41589 |
|
FYI I created this issue in the quarkus repository #41440 to discuss additional solutions to serve resources on the context-root even if a custom context path is used. |
There was a problem hiding this comment.
I've reviewed this PR, and aligned it with the RFCs contents. Some docs update might be missing, and I'll open a follow-up issue for that.
I also reviewed the previous comments. While I see that this won't work with the /auth prefix, this shouldn't keep us from merging this PR as is.
|
Follow-up docs task: #42323 |
closes #40923