fbpx

06. IdentityServer4 External Providers

You can find the project here.

Standard Protocols

All Identity Providers are supported using standard protocols like OpenID Connect, OAuth2, SAML2 and WS-Federation. This could be Okta, it could be Auth0, could be proprietary IdP of a client, could be another IdentityServer4. Take a look at the list of out-of-the-box extensions for “AuthenticationBuilder” for big providers like Azure AD, Microsoft Account, Google, Facebook, Twitter, etc here https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.authentication.authenticationbuilder?view=aspnetcore-2.2

Setting up the usual OpenID Connect OIDC middleware is enough for most of the providers to get you going. Almost all providers nowadays provide OIDC, some as a second option alongside SAML2 and/or WS-Fed.

As IdentityServer4 is OIDC Identity Provider you can actually set up one IdentityServer4 instance to be an external provider for another IdentityServer4 instance using OIDC middleware. As long as there is a single root node, all Identity Servers connected this way can achieve SSO.

 

Azure AD Example

I will continue from my last tutorial. Open the “Quickstart” solution in Visual Studio. Let’s add a NuGet package “Microsoft.AspNetCore.Authentication.AzureAD.UI”.

Open the “Startup.cs” in project root and navigate right above the “AddIdentityServer” service registration. Add the authentication middleware for AzureAD like so:

services.AddAuthentication()
	.AddAzureAD(options => Configuration.Bind("AzureAd", options));

services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
	options.Authority = options.Authority + "/v2.0/";
	options.TokenValidationParameters.ValidateIssuer = true;
	options.SignInScheme = IdentityConstants.ExternalScheme;
});

Add the missing “using” directives:

using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication;

Now open the “appsettings.json” in project root and modify it to add the Azure AD configuration we are using and binding in “Startup” like so:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=IdentityServerQuickstart;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "Data": {
    "Seed": false
  },
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "",
    "TenantId": "0366c849-xxxx-xxxx-xxxx-adcc0ccf2170",
    "ClientId": "7adeb3b0-xxxx-xxxx-xxxx-a6bc5aa756da",
    "CallbackPath": "/signin-oidc"
  }
}

Note: You must get your “TenantId” and “ClientId” (aka “ApplicationId”) from the Azure portal. Here are the official docs on how to create an app in Azure AD https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app

Tip: You will need the ReturnUrl for app registration. For this demo, the return URL is http://localhost:5000/signin-oidc

 

Okta Example

Open the “Startup.cs” in project root and navigate right below the “AddAzureAD” and add:

.AddOpenIdConnect("okta", "Okta", options => Configuration.Bind("Okta", options));

Also add the OpenIdConnectOptions service configuration like so:

services.Configure<OpenIdConnectOptions>("okta", options =>
{
	options.Scope.Add("openid");
	options.Scope.Add("profile");
});

So full code including Azure Ad and Okta looks like so:

  services.AddAuthentication()
	.AddAzureAD(options => Configuration.Bind("AzureAd", options))
	.AddOpenIdConnect("okta", "Okta", options => Configuration.Bind("Okta", options));

services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
{
	options.Authority = options.Authority + "/v2.0/";
	options.TokenValidationParameters.ValidateIssuer = true;
	options.SignInScheme = IdentityConstants.ExternalScheme;
});
services.Configure<OpenIdConnectOptions>("okta", options =>
{
	options.Scope.Add("openid");
	options.Scope.Add("profile");
});

Now open the “appsettings.json” in project root and modify it to add the Okta configuration we are using and binding in “Startup” like so:

"Okta": {
	"Authority": "https://dev-xxxxxx-admin.oktapreview.com",
	"ClientId": "0oakhxxxxxxxxxxaX0h7",
	"CallbackPath": "/signin-oidc-okta"
}

Note: You must get your “Authority” and “ClientId” from Okta. Here are the official docs how to create an Okta app https://developer.okta.com/docs/guides/add-an-external-idp/microsoft/register-app-in-okta/

Tip: You will need the ReturnUrl for app registration. For this demo, the return URL is http://localhost:5000/signin-oidc-okta

 

Modify the user auto-provisioning process

Because we added the “IsEnable” custom property in the previous tutorial the auto-provisioned user will by default have value “false” (disabled user) and the external provider login will fail. We need to slightly modify the automatic user creation process for external providers to set the “IsEnabled” flag to “true”. Navigate to “Quickstart/Account/ExternalController.cs” and open it.

Find the “AutoProvisionUserAsync” method and modify the line that instantiates new user. We need to modify it to set the “IsEnabled” user property to “true” like so:

var user = new ApplicationUser
{
	UserName = Guid.NewGuid().ToString(),
	Email = email,
	IsEnabled = true
};

Now run the IdentityServer4 and try to sign in with Azure AD or Okta. If the local user exists with the same username or email as the external user (from Azure AD or Okta in our example) the matching process will link the external user with local user and the new local user will not be created. For other scenarios (no match) the auto-provisioning process will create a new local user and link it with the external user. I logged in using Okta and the new local user was auto-provisioned. Notice that my name was automatically populated from the claims provided by Okta. These are the claims of the external user now set to the local user.

Too easy

Now that was super easy, wasn’t it? Adding any standard Identity Provider shouldn’t pose any challenge as the method is pretty much the same. In my next tutorial I will start tackling one of the important features which are Multi-Factor Authentication MFA aka 2FA if there are two factors. Stay fresh!

You can find the project here.

Support

For direct assistance schedule a technical meeting with Ivan to talk about your requirements. For a general overview of our services and a live demo schedule a meeting with Maja.