-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Add support for RFC 8707 OAuth2 Resource Indicators (#14355) #35711
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add support for RFC 8707 OAuth2 Resource Indicators (#14355) #35711
Conversation
d2ff0f1 to
7958620
Compare
|
Simple usage example EDIT: Client config for myclient
Initial Auth Request:-> This restricts the current auth session to use only Token RequestAccess Token responseDecoded Access Token with audience: {
...
aud: [foo]
}Token Refresh RequestAccess Token responseDecoded Access Token with audience: {
...
aud: [bar]
}Token Refresh request with invalid resourceAccess Token responseReturns error {"error":"invalid_grant","error_description":"Invalid resource"} |
7958620 to
84af69f
Compare
|
Haven't had a chance to look at this properly or think too much about it; but feels a bit like shoehorning/abusing protocol mappers, and not a natural way to manage resources for a client. I think how we want to support resource indicators in Keycloak is better done first as a design/discussion rather than a PR. |
|
Few random thoughts around this:
|
84af69f to
f150b10
Compare
|
Yes, I agree this is somewhat abusing the protocol mappers mechanism beyond token generation since it also alters the Authorization Server behaviour. However, I felt quite pragmatic to do so. However, I agree that this protocol mapper usage might be uncommon - but I have to start somewhere :O) Also the implementation can easily changed to load the resource identifiers list from somewhere else :)
I understand the use-case. I added the point to the discussion.
Yes, that's written in the spec and the resource examples I gave were just that, examples. Quite often Keycloak users also model resource servers / APIs as clients without flows in Keycloak to configure client specific roles etc, that can be used by other clients. In my mind resource identifiers == client_id for resource server clients, my be this is a bit off, but since client_ids are usually not URIs (at least it's not enforced) I used non-URI values as resources in the examples.
Noted, and added to the discussion.
Sometimes the configured base URL might not necessarily match the resource identifiers. I'm thinking of deployments of a resource server in different environments (dev, test, qa, prod), where the base URL is different but the logical resource URIs might be the same for all environments.
I think the resources in authz services could indeed be used for this, but this would lead to a stronger coupling of the authorization services with the oauth2 functionality which might cause other problems. We then would also need a way to let clients "opt-in" to the resource identifier support somehow, perhaps with an "advanced setting" in the client configuration: |
f150b10 to
bbe2913
Compare
|
I refactored this the resource indicator support a bit:
We could then add a default implementation that checks given resource identifiers based on something like a component config (config per client) etc. |
bbe2913 to
f21d068
Compare
9753f35 to
53facf8
Compare
53facf8 to
464c2cf
Compare
464c2cf to
9df551f
Compare
|
Nice work 👏. |
|
Thanks @cgeorgilakis for your feedback. The handling of the |
9eea73b to
c9eb21c
Compare
c9eb21c to
fd19563
Compare
|
The latest version of the PR uses authorization-services resources to describe the resource indicators that are available to a client. ... with authorization enabled Resources can be defined via Authorization / Resources in the client: The custom type: Available resource indicators for a client can be seenin the resources tab: A new One can find an example realm and some http request examples with curl here: https://gist.github.com/thomasdarimont/0ccab1238d3824a84a37a16a086cf890 |
fd19563 to
2366d80
Compare
Unreported flaky test detectedIf the flaky tests below are affected by the changes, please review and update the changes accordingly. Otherwise, a maintainer should report the flaky tests prior to merging the PR. org.keycloak.testsuite.cluster.UserFederationInvalidationClusterTest#crudWithFailover |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unreported flaky test detected, please review
2366d80 to
08a3f08
Compare
- Adds ResourceIndicatorMapper OIDC protocol mapper - Make AuthorizationEndpoint and Token Endpoint aware of resource parameter. - Enhanced Authz request parsing to support repeated parameter (resource) If the authorization request contains one or more resource parameters, those resource values are first checked against the list of allowed resource indicator patterns for the given client. If the resource indicators are legit for the client, the initially requested resource identifier set is stored in the client session. Token Requests / Token Refresh Requests can later request access tokens minted to support resource indicators in the aud claim based on the resource indicators that were initially requested. Note that this allows users to dynamically extend or narrow down the audience based on the given resource identifiers in token / token refresh requests. The allowed resource identifiers for a client are managed via the ResourceIndicatorMapper. ResourceIndicatorMapper manages aud claim via resource parameters. Users can configure the list of allowed resource indicator patterns in the ResourceIndicatorMapper configuration for a client. Note that only resource indicators allowed by the mapper configuration can be requested for a client. Fixes keycloak#14355 Signed-off-by: Thomas Darimont <[email protected]> Refactor ResourceIndicator handling - Introduced OAuth2ResourceIndicatorsProvider SPI to abstract how valid Resource Indicators for clients are determined - Revised the resource parameter checking - Removed configuration of resource indicators from ResourceIndicatorMapper Signed-off-by: Thomas Darimont <[email protected]> Add an example default implementation for OAuth2ResourceIndicatorsProvider Signed-off-by: Thomas Darimont <[email protected]> Revise code in flattenDecodedFormParametersToParamsMap Signed-off-by: Thomas Darimont <[email protected]> Revise OAuth2ResourceIndicatorsProvider - Rename SPI to resource-indicator-resolver - Rename to OAuth2ResourceIndicatorsProvider - Add ability to lookup clients by resource indicators Signed-off-by: Thomas Darimont <[email protected]> Next iteration for RFC 8707 OAuth2 Resource Indicators support - We now allow specifying supported resource indicators via the authorizations tab in the client configuration. - Users can declare new resources with the special type URI: `urn:keycloak:resource-identifier` to denote an resource identifier. - According to the RFC 8707, resource indicators must be URIs, but we also support Keycloak clientIds as allowed resource indicators to support existing Keycloak realm configurations. Signed-off-by: Thomas Darimont <[email protected]> Change KEYCLOAK_RESOURCE_INDICATOR_TYPE to urn:keycloak:oauth2:resource-identifier Signed-off-by: Thomas Darimont <[email protected]> Revise DefaultOAuth2ResourceIndicatorResolver Signed-off-by: Thomas Darimont <[email protected]> Validate resource parameter during token exchange. Signed-off-by: Thomas Darimont <[email protected]> Change KEYCLOAK_RESOURCE_INDICATOR_TYPE to urn:keycloak:oauth2:resource-indicator Signed-off-by: Thomas Darimont <[email protected]> # Conflicts: # services/src/main/java/org/keycloak/protocol/oidc/grants/OAuth2GrantTypeBase.java # services/src/main/java/org/keycloak/protocol/oidc/tokenexchange/AbstractTokenExchangeProvider.java
08a3f08 to
87884d8
Compare
stianst
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should limit the initial support of resource indicators to a client having a single resource uri.
That brings the question of what resource can a client requests; for that we would need a way to link the client to the audience clients. Which is something we are aiming to deliver in #43179
We could leverage client roles though for this purpose perhaps? We could use something like the following:
- Add an optional Resource URI attribute to clients
- Get a list of all clients the client has a client role scope on
- For each
resourceparameter check it matches theResource URIof one of the clients from 2
I changed this to a draft since there are no tests at all; I'd suggest we break this up into multiple stages starting with only supporting resource parameter in authorization request and token requests grant types authorization_code and refresh_token.
|
@thomasdarimont do you want to proceed with this PR or should I or someone else take over? |
|
Thanks @stianst for picking this up again. I don't have time to work on this today / next few days. So if you want to work on this now feel free to adopt it. Moving forward, instead of continuing this PR, we should close it and create a new one. Some questions/thoughts regarding your proposal:
Q1) How to configure the (primary) resource indicator for a client? With this, we would only allow one (primary?) resource indicator per client for now, which can be used as an alias to target this specific client/resource server via the Q2) Mechanism to select the eligible resource indicators for a given client To verify this: Is this what you had in mind? Q3) How to match a client via resource indicator to the requested Using the client role scope to select clients and derive the eligible resource indicators is a simple solution. Still, it requires additional configuration (role definitions) and is also limited to just one indicator (which is fine for now). However, I wonder if we should make this pluggable from the start and use a new SPI to derive eligible resource indicators for a client with it (a default implementation could use the client role scope for this purpose). Q4) How do we specify whether a client supports the resource parameter or not? Q5) When and where do we determine the eligible resource indicators? |
I don't either right now, but want to make sure we get this sorted and included in 26.5. We can work together on this in some form :)
I'm not actually convinced it has to be unique, or at least not enforced at the DB level. Only thing that would happen if two services are registered with the same resource URI is that a client would pick one; or if it only has a relationship with one then it will ignore the other. If there is a duplicated; we don't know if it's the first or the second that is using the wrong resource URI; or maybe actually in fact there is two clients for a given service, and it uses them for different purposes. With what I'm proposing below when clients and services are linked this also becomes less of an issue.
Something along those lines; let's continue the discussion around that in #43179 For resource indicators let's assume there is a way to list all clients a client can connect to, so that we have a limited set of clients to look for matching resource indicators.
I'd start without it being pluggable - it's just less code and things to test; however, don't have any issues with a quick follow-up that makes it pluggable.
Don't think we need that if we have what I talk about above; it's basically supported as long as a client is connected to a different client that has a resource-uri configured
Not really following what you are saying here. What is an eligible resource indicator? How would a user request a subset? Are you talking about optional consents or something? |
|
Yes let's do this together :) I can send a new PR with just the minimal bits to support a new "Root Resource URI" client attribute for clients. I guess this setting should be placed in the "Advanced Settings" somehow and be empty by default. |
Add support for RFC 8707 OAuth2 Resource Indicators (#14355)
Discussion: #35743
ResourceIndicatorMapperOIDC protocol mapper to manage theaudclaim based on theresourceparameterAuthorizationEndpointandTokenEndpointaware ofresourceparameter.OAuth2ResourceIndicatorResolverSPI to allow filtering of resource indicators and lookup associated clients for resource indicatorsIf the authorization request contains one or more resource parameters, those resource values are first checked against the list of allowed resource indicators for the given client. Allowed resource indicators are determined
via the
OAuth2ResourceIndicatorResolverSPI.If the resource indicators are legit for the client, the initially requested resource identifier set is stored in the client session.
Token Requests / Token Refresh Requests can later request access tokens minted to support resource indicators in the
audclaim based on the resource indicators that were initially requested.Note that this allows users to dynamically extend or narrow down the
audclaim based on the given resource identifiers in token / token refresh requests.Fixes #14355
Signed-off-by: Thomas Darimont [email protected]