Skip to content

MIKE Cloud Authentication

The Domain Services (DS) web APIs are protected using token based authentication. DS provides a complete out-of-the box Authorization Server - including a React-UI for managing user accounts.

However, due to the decoupled nature of DS, this approach is exchangeable. This guide describes how to set up a web-based flow to sign-in (authenticate) users using MIKE Cloud (Azure AD) as the identity provider. This flow is based on the OpenID Connect protocol. To get an overall understanding of this flow, you should watch this 6 minutes video.

The authentication flow

A Domain Services web application is a single-page application (SPA) on top of a web API. For such an application, the authentication flow will be the following:

  1. From a browser the user tries to access the web application without a valid token (either expired, missing or otherwise malformed).
  2. Since the application (or more specifically the web API of the application) is configured to trust MIKE Cloud (Azure AD) as an identity provider, the user is redirected to Azure AD for authentication. A URL template for this redirect is described later in this guide.
  3. The user is signing in, for example by entering username and password in a form (and possibly more factors like a one-time password from an authenticator, depending on how the system is configured).
  4. When the user is properly authenticated, Azure AD will issue an OpenID token and redirect to a predefined, whitelisted, URL (see Registering the application in MIKE Cloud). This HTTP POST request will contain the OpenID token that can be used to access endpoints in the web API (as a bearer token).

Once the user has successfully signed in, she will no longer be prompted for credentials (step 3 being bypassed).

This flow also supports single sign-on.

Prerequisites

Before you can configure this authentication flow for your application, there are a couple of things that needs to set up in MIKE Cloud. You have to register the application in MIKE Cloud and create customers and users.

Registering the application in MIKE Cloud

MIKE Cloud uses Azure AD for its authentication. The first step is to register your DS application in Azure AD. This is a manual process that has to be completed by the administrators of MIKE Cloud.

The person who creates the application in MIKE Cloud needs to know the following:

  • That you need an OpenID token generated.
  • The URL(s) the application can redirect to after a successful login of the user. You can choose to have multiple URLs - for example one for test and one for production.
  • Additional claims that you want on the OpenID token - for example CustomerId, CustomerName, CustomerDisplayName etc.

When the application is registered you'll receive an application id (GUID) and a tenant id (GUID).

Creating customers and users

MIKE Cloud segments its users into customers. A customer could be a company or a department within a company. For example, the DHI departments are added as customers in MIKE Cloud and the individual employees are added as users.

To create a customer, navigate to DHI BackOffice and create a customer with users. If you do not have access to the BackOffice application, ask a MIKE cloud administrator for help.

To create a customer the customer name and Maconomy number has to be supplied. For user registration, their name and email address is required. An email invite will be sent to the user and the user will choose a password for their account.

Configuring MIKE Cloud authentication in a web API

To configure MIKE Cloud authentication in a Domain Services web API, you must do the following:

Install the Microsoft.Identity.Web NuGet package

In startup.cs the authentication section must be configured like this:

public void ConfigureServices(IServiceCollection services)
{
  ...
  services.AddMicrosoftIdentityWebApiAuthentication(Configuration);
  ...
}

Furthermore, a new configuration section has to be added to your appsettings.json file:

{
  ...
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "localhost",
    "TenantId": "<tenant-id>",
    "ClientId": "<application-id>",
    "CallbackPath": "/signin-oidc",
    "AllowWebApiToBeAuthorizedByACL": true
  },
  ...
}

The <tenant-id> and <application-id> placeholders have to be replaced with the actual identifiers (GUIDs).

The Domain Services web API components rely on two policies for authorization ("AdministratorsOnly" and "EditorsOnly"). Some endpoints are only accessible, if the requesting user fulfill the requirements of these policies. Normally, these policies are based on user claims - typically roles or group memberships.

If you, during application registration, have asked for example for the CustomerId to be included as a claim in the OpenID token, you can create policies based on this information. In the below example all DHI users are regarded as administrators (and every authenticated user is given editor privileges).

private static void ConfigureAuthorizationOptions(AuthorizationOptions options)
{
    options.AddPolicy("AdministratorsOnly", policy => policy.RequireClaim("CustomerId", "DHI"));
    options.AddPolicy("EditorsOnly", policy => policy.RequireAuthenticatedUser());
}

However, if the token issued from MIKE Cloud doesn't include such claims, these policies can be "bypassed" by configuring policies that just require the user to be authenticated.

private static void ConfigureAuthorizationOptions(AuthorizationOptions options)
{
    options.AddPolicy("AdministratorsOnly", policy => policy.RequireAuthenticatedUser());
    options.AddPolicy("EditorsOnly", policy => policy.RequireAuthenticatedUser());
}

This means that any authenticated user will be able to access any endpoint.

Alternatively, if you need even more control, you can use the below description of how to extend an OpenID token with additional claims and use this to establish claims-based policies.

NOTE: The Visual Studio project template called "MIKE Cloud Web API" is configured as described above and pre-installed with the MIKE Cloud Provider. The Domain Services Visual Studio project templates can be installed from DHI Software Center.

Requesting the OpenID token

To redirect authentication to retrieve an OpenID token from MIKE Cloud, the application must navigate to the following URL template:

https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize?client_id=<application-id>&redirect_uri=<redirect-uri>&response_type=id_token&scope=openid%20profile&response_mode=form_post&nonce=<random-string>

The <tenant-id>, <application-id>, <redirect-uri> and <random-string> placeholders have to be replaced by the actual values. The <redirect_uri> parameter has to be URL encoded.

For the above example when the user is successfully authenticated, the browser will make a HTTP POST request to the specified redirect-uri containing a form with parameters id_token and session_state. The id_token is what we are after.

The OpenID token is a JSON web Token (JWT) and can be validated using standard OpenID Connect protocols.

Extending an OpenID token with additional claims

If the OpenID token issued from MIKE Cloud doesn't include the necessary claims to configure proper authorization, you can hook into the ASP.NET authorization pipeline and add application-specific claims to the user after authentication (token validation):

  public void ConfigureServices(IServiceCollection services)
  {
    ...

    services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
    {
      var existingOnTokenValidatedHandler = options.Events.OnTokenValidated;
      options.Events.OnTokenValidated = async context =>
      {
        var claims = new Claim[]
        {
          new Claim(ClaimTypes.GroupSid, "Editors")
        };
        var appIdentity = new ClaimsIdentity(claims);
        context.Principal.AddIdentity(appIdentity);
        await existingOnTokenValidatedHandler(context);
      };
    });

    ...
  }

If you have asked to include for example the CustomerId as a claim in the OpenID token, you can create new claims based on this information. For example, in the below example all DHI users are regarded as administrators (and the rest editors).

  public void ConfigureServices(IServiceCollection services)
  {
    ...

    services.Configure<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme, options =>
    {
      var existingOnTokenValidatedHandler = options.Events.OnTokenValidated;
      options.Events.OnTokenValidated = async context =>
      {
        var customerId = context.Principal.FindFirstValue("CustomerId");
        var claims = new Claim[]
        {
          new Claim(ClaimTypes.GroupSid, customerId == "DHI" ? "Administrators" : "Editors")
        };
        var appIdentity = new ClaimsIdentity(claims);
        context.Principal.AddIdentity(appIdentity);
        await existingOnTokenValidatedHandler(context);
      };
    });

    ...
  }

Single sign-on

Single sign-on makes it possible for users to navigate between different web applications without having to enter credentials (username and password) multiple times. For an overall description of single sign-on, you should watch this 4 minutes video.

You can easily configure single sign-on, simply by having multiple applications trusting MIKE Cloud as the identity provider.