0

I am looking for any specifications, prior art, and known security considerations for a specific OAuth2 use case where:

  • an authorization code grant is being performed.
  • the client does not know the resource server ahead of time.
  • the resource server will be determined by the authorization server, e.g. based on the user's identity.

You can imagine that the authorization server is used as an entryway to many resource servers where each user is assigned to just one resource server, and the authorization server issues credentials that the resource servers can verify. Once the client receives credentials from the token endpoint it needs to infer the resource server and then begin communicating with it.

I am aware that the access token may contain an audience field (or be introspected via an endpoint as in RFC 7662), but my impression is that the intention is for the audience to be verified by the resource server, not intended to be utilized by the client. I could imagine security implications of the authorization server dictating which resource server the client should talk to, but I haven't found any good material on this. I also haven't come across any specifications with this use case in mind, describing how the authorization server should indicate the resource server to the client (in the access token? in a response field from the token endpoint?).

If anyone has experience with this or knows of any standard approaches I'd greatly appreciate your thoughts.

2 Answers 2

0

I don't have citations for this, but: there's no harm in specifying an audience in the JWT, having it be a specific resource server, and expecting the client to inspect the JWT to identify the resource server. The resource server(s) still can - and should - verify that they are the intended audience, such that a misbehaving client can't use a a token for resource server X to access resource server Y.

That's probably the "most OAuth-y" way to do it, but there's other options too. The authorization server could add an additional field to either the client redirect (an extra URL parameter, assuming you redirect via GET) or the token grant response (in the response body, or a header for that matter), telling the client what resource server to use. Or the RS to use could be in the token but in a different field from aud, if you want to treat it as e.g. a "scope" rather than an "audience". It would still be a good idea to have the RS verify that it's the one intended for a given token.

So long as you leave it possible for the resource server to verify that the access token is intended for itself, that the access token is valid, and what access the access token authorizes, there's no harm in passing additional non-secret (to either client, auth server, or resource server) information during an OAuth flow. Obviously you should still use the standard OAuth hardening - things like PKCE, restricting and verifying the redirect URIs, setting and verifying state, using a minimal scope, using a very short-lived JWT access token plus a refresh token, etc. - but nothing about your scheme weakens OAuth.

2
  • Thanks for confirming that. I have one nagging thought on this. If a counterfeit AS is able to offer the user some credentials, it's somewhat mitigated by a well-behaved RS verifying them and considering them invalid. However, in this case the counterfeit AS would also be able to direct the user to a counterfeit RS where the credentials may appear to be valid. I'd be interested to hear what you think about this scenario.
    – Devin Ivy
    Oct 25, 2023 at 4:32
  • Depends what you mean by "counterfeit AS". If you mean one that doesn't have access to the JWT signing key and doesn't have access to valid JWTs at all, it's not a problem; the resource servers are responsible for verifying the JWT, and they won't be able to, because it won't have a valid signature for the AS's public key. They'll reject the request as though somebody had sent it without going through OAuth at all. A fake AS can share a valid access token if it has one, but that only harms whoever the token is for, not your service. If the fake AS has your private key, it's game over, always.
    – CBHacking
    Oct 25, 2023 at 7:03
0

You can use resource_access claim. It lists client IDs together with their roles.

"resource_access": {
    "client_bob": {
        "roles": [
            "bob_client_role"
        ]
    }
}

If the client ID of Bob is present in the audience claim, then Alice will have resource access to Bob's resource. Here's how to configure audience.


Another way is to create a custom user attribute that names access to resource servers. Here's how:

Step-1: User Attribute

You can define a custom user attribute on a user, say alice, or on a group of users. Give any unique name as a key and a string as value identifying the resource server. The value can also be an array to include multiple values (multiple resource servers in your case). E.g. {"access_to": "bob_url"}

Step-2: Client Scope Creation

Create a client scope, say my_client_scope.

Step-3: User Attribute Token Mapper

Map the user attribute access_to to the client scope my_client_scope by configuring a User Attribute token mapper inside that client scope.

Step-4: Client Scope Assignment

Assign that client scope to the client, say client_alice, as default or optional (recommended).

Now your access token will have a custom claim access_to whose value can be an array or a string URL of a resource server you want to authorize access to.


Note: In both ways, audience claim should be configured as merely declaring a resource server in the access token is not enough to assume that the resource server will allow access.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .