RockSolidKnowledge / TokenExchange

Token Exchange (RFC 8693) implementation for IdentityServer
Apache License 2.0
17 stars 0 forks source link

Support for subject- less tokens (client credential grant) #1

Open bmcclory opened 2 years ago

bmcclory commented 2 years ago

Hello there! Thanks for creating this library. Question about:

https://github.com/RockSolidKnowledge/TokenExchange/blob/b999e7738f2b6fd7ee5fa4eebabc9dde6d73748b/src/Rsk.TokenExchange.IdentityServer4/TokenExchangeExtensionGrantValidator.cs?_pjax=%23js-repo-pjax-container%2C%20div%5Bitemtype%3D%22http%3A%2F%2Fschema.org%2FSoftwareSourceCode%22%5D%20main%2C%20%5Bdata-pjax-container%5D#L90

I understand from the error message (and my own digging) that IdentityServer4 indeed makes it difficult to create a custom GrantValidationResult for a subject- less token. Its pipeline for attaching claims to tokens is primarily aimed at (human) users -- principals with a subject claim. The IProfileService, and the configured claims for scopes/resources, are only invoked for token requests with a subject.

By design, IdentityServer4 does not emit a subject claim for tokens issued via the client credentials grant. So out of the box, this library cannot exchange tokens that are issued from that flow.

Question: Is there any particular reason for this limitation -- i.e. some security reason why it wouldn't make sense to exchange "client" tokens in the same manner as "user" tokens? Would you accept a PR to add support for "client" token exchange?

andrewclymer commented 2 years ago

Hi Bret

Thanks for your feedback. The main focus of Token Exchange is to allow the initial protected resource to obtain further tokens to access to complete the request without the need for user interaction. With client credential flow there is no user interaction, so the protected resource could just request a new token, no need to perform an exchange. Are you able to share your use case as that might help to understand fully the problem you are trying to solve?

All the best

Andy


Rock Solid Knowledge Ltd is a company registered in England and Wales under number 6811209. Registered office: C2, Vantage Office Park, Old Gloucester Road, Bristol, BS16 1GW, United Kingdom ​Vat registered: GB948 1966 72 . From: Bret McClory @.> Sent: 05 November 2021 02:02 To: RockSolidKnowledge/TokenExchange @.> Cc: Subscribed @.***> Subject: [RockSolidKnowledge/TokenExchange] Support for subject- less tokens (client credential grant) (Issue #1)

Hello there! Thanks for creating this library. Question about:

https://github.com/RockSolidKnowledge/TokenExchange/blob/b999e7738f2b6fd7ee5fa4eebabc9dde6d73748b/src/Rsk.TokenExchange.IdentityServer4/TokenExchangeExtensionGrantValidator.cs?_pjax=%23js-repo-pjax-container%2C%20div%5Bitemtype%3D%22http%3A%2F%2Fschema.org%2FSoftwareSourceCode%22%5D%20main%2C%20%5Bdata-pjax-container%5D#L90

I understand from the error message (and my own digging) that IdentityServer4 indeed makes it difficult to create a custom GrantValidationResult for a subject- less token. Its pipeline for attaching claims to tokens is primarily aimed at (human) users -- principals with a subject claim. The IProfileService, and the configured claims for scopes/resources, are only invoked for token requests with a subject.

By design, IdentityServer4 does not emit a subject claim for tokens issued via the client credentials grant. So out of the box, this library cannot exchange tokens that are issued from that flow.

Question: Is there any particular reason for this limitation -- i.e. some security reason why it wouldn't make sense to exchange "client" tokens in the same manner as "user" tokens? Would you accept a PR to add support for "client" token exchange?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://github.com/RockSolidKnowledge/TokenExchange/issues/1, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ABXMTTITPNG5FOADLV6CA3TUKNCL3ANCNFSM5HM2C2QQ. Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

bmcclory commented 2 years ago

Hi Andy, thanks for the quick reply.

In a microservices architecture with an API gateway, external clients should have restricted access: They can only obtain tokens for the "gateway" audience. The gateway would use its credentials to obtain tokens for the backend microservice audience(s).

Furthermore, IdentityServer4 allows applications to define "Client Claims", which by default are emitted in the token in "client credential" flow (or all flows when AlwaysSendClientClaims option is enabled). This is where Token Exchange becomes interesting: Rather than having the gateway simply request a new token as itself, we'd like any client claims associated with the original client to be preserved (reissued) in the new token.

From an audit / traceability standpoint, it'd also be interesting to see an act claim on issued tokens, to record the fact that "gateway" is acting on behalf of the original client.

On a related note, the idea of preserving client claims during Token Exchange might make sense in general, not just this client credential special case. This library (per specification?) already impersonates the original client (by using its client_id, and tucks the exchange requestors client ID into the act claim). Perhaps other claims associated with the original client (i.e. configured client claims) should be impersonated in the same way. We can override the UpdateRequest method in the TokenExchangeExtensionGrantValidator to achieve that behavior. But we can't overcome the limitation of "subject- less" tokens without replacing the entire validator with our own.