My doubt is this: is it possible to use an external identity provider when using OAuth to protect a single RESTful API?
Yes, it is definitely possible. This is exactly what you do when you use Azure Active Directory to protect your API endpoints:
app.UseOAuthBearerAuthentication(options => { options.AutomaticAuthenticate = true; options.Authority = "https://login.windows.net/tushartest.onmicrosoft.com"; options.Audience = "https://TusharTest.onmicrosoft.com/TodoListService-ManualJwt"; });
The next legitimate question is: if you can use tokens issued by AAD to protect your API, why couldn't you do the same with Facebook or Google tokens?
Unlike Facebook or Google, AAD produces fully standardized tokens with JWT names, which the OAuth2 link can “read” and “check” to determine if the token is valid and really was released for your API (i.e. if the audience attached by a marker corresponds to your API, which can be used with the resource parameter when executing your authorization request).
You cannot do something similar with FB or Google tokens, as they are completely opaque. In fact, this is not surprising, since these tokens have only one goal: to allow you to request FB or Google APIs, and not your own (these social providers do not allow you to set an access token audience).
Since you cannot read the token yourself, the only option is to ask FB or Google if it is valid to make sure your API does not accept invalid tokens. This is what you can (easily) do with Facebook, as they offer a “marker validation checkpoint”, you can request for this: https://developers.facebook.com/docs/facebook-login/manually-build-a -login-flow (see chapter "Checking the access peephole"). Thus, you can guarantee that the token has not expired and determine the user corresponding to the token.
Unfortunately, this approach has two drawbacks:
- You need to make an additional HTTP call to the Facebook endpoint in order to verify the access token, which means caching the received tokens in order to avoid flooding Facebook with too many requests.
- Since the access token is not issued for your own API, you MUST fully guarantee that the access token has been issued to a client application that you fully trust , or that it will allow any third-party developer to use its own FB / Google tokens with your API without requiring user consent . This is obviously a serious security issue.
You can find more information in the last part of this SO answer (this is for Katana and Dropbox, but you should get this idea): OWIN / OAuth2 Third-party login: authentication from the client application, authorization from the web API
So my question here is: when using OAuth and ASP.NET 5, is it possible to use an external identity provider besides its implementation? If possible, how does it work shorter? I mean, my application should still be able to manage user IDs, in the sense that it needs to manage claims, etc.
In this case, if it is really possible, what will the flow be? Should an external identity provider issue tokens? But how will my application be able to verify these tokens and manage user IDs?
To get around the limitations mentioned in the previous part, the best option - as you already found out - is to create your own authorization / authentication server. Thus, your API does not accept (directly) FB or Google tokens, but tokens issued by your own server, which can redirect your users to FB or Google for authentication.
This is exactly what this sample does: https://github.com/aspnet-contrib/AspNet.Security.OpenIdConnect.Server/tree/vNext/samples/Mvc
The user is invited by the client application (Mvc.Client) to authenticate from your authorization server (Mvc.Server) so that he can get the access token for the subsequent API request (also in Mvc.Server). To do this, the user is redirected to your authorization server, which itself offers you to authenticate using Google or Twitter.
When this external authentication step is completed, the user is redirected back to your authorization server (Mvc.Server), where he asked to give his consent to the client application (Mvc.Client) to access his personal data.
When consent is given, the user is redirected back to the client application using an access token, which you can use to request the API endpoint.