Search code examples
openiddict

Using Openiddict for user identity management and application access


I have a .NET Core web API that uses openiddict for identity management that is tied to ASP.NET identity in a SQL server backend. Many applications can leverage this API with a subscription. I have the following requirements.

  1. Only authorized applications can use the API
  2. Each application can optionally use the identity features of the API to manage their application specific users as implemented by Openiddict within the API (currently the authorization, password, and refresh token flows are enabled).
  3. All endpoints should require that an application be in the Oppenidict application table and this application ID should be available on every request due to multi-tenant support in the API.
  4. Endpoints that have an [Authorize] attribute must be have a user that is authenticated via the Openiddict identity model.

To implement requirement (1), would I need to implement a custom authorization function that checks for an application secret or should another flow be enabled in openiddict that takes care of ensuring only authorized applications are allowed access to the API (regardless of authorize attributes)? In this case, a user may not be authenticated, but the application must still have rights to access the non-authorized endpoints of the API.

To implement requirement (2) for external identity providers, is it possible to configure multiple secrets for each application registered within openiddict to allow their users to leverage facebook or twitter for authentication? This is important, because the API would need call AddFacebook() during configuration for each application that can access the API (not the clientID and secret of the API itself). Because multiple applications each have their own facebookID and secret, I would assume this would only work if openiddict could allow the registration of multiple Ids and secrets for the same provider type via AddFacebook() for example.

To implement requirement (3), is there a built in way to get the application ID of the calling application from openiddict like there is if the user was authenticated?


Solution

  • To implement requirement (1), would I need to implement a custom authorization function that checks for an application secret or should another flow be enabled in openiddict that takes care of ensuring only authorized applications are allowed access to the API (regardless of authorize attributes)?

    Starting with RC3, client identification was made mandatory by default: if you don't send a client_id corresponding to an entry in the applications table, your request will be rejected by OpenIddict itself. In previous versions, you could opt for this feature by calling options.RequireClientIdentification() (it's now opt-out).

    To implement requirement (2) for external identity providers, is it possible to configure multiple secrets for each application registered within openiddict to allow their users to leverage facebook or twitter for authentication? This is important, because the API would need call AddFacebook() during configuration for each application that can access the API (not the clientID and secret of the API itself). Because multiple applications each have their own facebookID and secret, I would assume this would only work if openiddict could allow the registration of multiple Ids and secrets for the same provider type via AddFacebook() for example.

    There's no direct relationship between OpenIddict and the authentication schemes you use, so no, you can't configure multiple Facebook credentials "via" OpenIddict as the two are unrelated.

    Assuming you need that for multitenancy purposes, you may want to read https://stackoverflow.com/a/49682427/542757 to learn how you can override ASP.NET Core's default options monitor so you can provide tenant-specific options for authentication handlers like OpenIddict, Facebook, Google and anything else.

    To implement requirement (3), is there a built in way to get the application ID of the calling application from openiddict like there is if the user was authenticated?

    Assuming it's known (i.e you didn't explicitly make client identification optional in the OpenIddict options), yes. E.g from a MVC controller:

    var result = await HttpContext.AuthenticateAsync(OpenIddictValidationDefaults.AuthenticationScheme);
    Debug.Assert(result.Ticket != null, "The authentication ticket shouldn't be null.");
    
    // The presenters list contains the authorized parties allowed to
    // use the access token with your APIs. Usually, it contains a single value.
    // Note: this extension requires a using for AspNet.Security.OpenIdConnect.Extensions.
    var client = result.Ticket.GetPresenters().FirstOrDefault();