IdentityModel / AuthorizationServer

Sample implementation of an OAuth2 Authorization Server
Other
280 stars 136 forks source link

Best approach for client accessing multiple apps #214

Closed ghys closed 10 years ago

ghys commented 10 years ago

Hi! Not really an issue with AS per se, but I'd like to pick Dominick's/Brock's brain to solve a somewhat interesting problem with application/audience fragmentation ;)

So basically I have a bunch of apps (say app1, app2, app3, app4, app5) each consisting in an API (let's call them api1...api5) and their 'official'/primary pure JS client (AngularJS SPAs - client1...client5). I therefore registered the apps and clients in AS, each client being allowed to retrieve a token for their own app and the 'all' scope I defined, using the implicit flow - the token is stored in session storage, maintained by the client, sent in the Authorization header for each API call... this works quite well! As for the APIs, they are configured to accept those bearer tokens for their own audience only i.e. for api1: app.useJsonToken(issuer: "MyAuthSrv", audience: "app1", signingKey: "xyz")

Now the challenge is, I'd like a client to be able to consume resources of another app's API; for example client1 wants some data out of api2, api4 and api5.

Here are the solutions I considered: 1) 'proxifying' the needed endpoints in api2, api4, api5 through api1, but this would become an unmaintainable mess rather quickly IMO. 2) defining a single 'merged' application in AS whose tokens' audience would be accepted as an allowed audience by all APIs, and segregating the individual APIs using scopes. This would work but I actually wired a custom claims transformer in AS inherited from ClaimsTransformerBase, to enrich the access token with a few additional claims (actually a filtered table of permissions) used at the API level for resource-based authorization - so the target audience is actually important. 3) having the clients perform additional implicit flows to retrieve tokens for each API they need to use besides their own - this is rather ugly because this would result in as many browser redirect roundtrips, from an user perspective this is not ideal. 4) I could have 5 additional assertion flow clients in AS, said assertion being the JWT token client1 already got for api1 from AS. This could actually be a urn:ietf:params:oauth:grant-type:jwt-bearer grant type as specified in http://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-09. The implementation of IAssertionGrantValidation would validate it and exchange it for a token for the requested additional audience i.e. app2, app4, app5. The original client (client1) would then maintain and use it appropriately as it would for its own backend api1.

I'm leaning towards 4) but I wanted to run it by you, in order to make sure I'm headed in the right direction.

What do you think? Thanks in advance!

leastprivilege commented 10 years ago

I would use 2) and do your claims transformation rather based on the scopes than the audience.

ghys commented 10 years ago

Yes, the more straightforward the better I guess. This option was one of the favorites along with the assertion/token exchange thing anyway. I'm closing the issue... thanks for your advice!