Implement an OpenIddict identity provider using ASP.NET Core Identity with Keycloak federation

This post shows how to setup a Keycloak external authentication in an OpenIddict identity provider using ASP.NET Core identity.

Code: https://github.com/damienbod/AspNetCoreOpeniddict

Setup

The solution context implements OpenID Connect clients which use an OpenIddict identity provider and ASP.NET Core Identity to manage the accounts. All clients authenticate using the OpenIddict server. Keycloak is used as an external authentication provider on the OpenIddict identity provider. Users can be created in either identity provider. If only users are created on the Keycloak server, the direct sign in with username, password can be completely disabled in the OpenIddict server. This setup allows for great flexibility and the MFA can be forced anywhere depending on the requirements. Companies using the product can use their own identity provider.

Integrating an OpenID Connect conform client is really simple in ASP.NET Core and no extra Nuget packages are required. You only need extra packages when the IDP are not conform or do something vendor specific. The AddOpenIdConnect method is used to implement the Keycloak server. I set this up using this github repo and the Keycloak docs. The SignInScheme needs to be set to the correct value. ASP.NET Core Identity is used to map the external identities and the “Identity.External” is the default scheme used for this. If you need to disable local identity users, the ASP.NET Core Identity logic can be scaffolded into the project and adapted.

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
	.AddOpenIdConnect("KeyCloak", "KeyCloak", options =>
	{
		options.SignInScheme = "Identity.External";
		//Keycloak server
		options.Authority = Configuration.GetSection("Keycloak")["ServerRealm"];
		//Keycloak client ID
		options.ClientId = Configuration.GetSection("Keycloak")["ClientId"];
		//Keycloak client secret in user secrets for dev
		options.ClientSecret = Configuration.GetSection("Keycloak")["ClientSecret"];
		//Keycloak .wellknown config origin to fetch config
		options.MetadataAddress = Configuration.GetSection("Keycloak")["Metadata"];
		//Require keycloak to use SSL
		
		options.GetClaimsFromUserInfoEndpoint = true;
		options.Scope.Add("openid");
		options.Scope.Add("profile");
		options.SaveTokens = true;
		options.ResponseType = OpenIdConnectResponseType.Code;
		options.RequireHttpsMetadata = false; //dev

		options.TokenValidationParameters = new TokenValidationParameters
		{
			NameClaimType = "name",
			RoleClaimType = ClaimTypes.Role,
			ValidateIssuer = true
		};
	});

The Keycloak configuration is added to the app.settings. We do not need much, a standard OpenID connect confidential code flow client with PKCE is setup to authenticate using Keycloak. This can be adapted, changed in almost any way depending on the server requirements. You should stick to the standards when implementing this. Using PKCE is required now on most deployments when using the OIDC code flow. Any identity providers solutions which does not support this should be avoided.

  "Keycloak": {
    "ServerRealm": "http://localhost:8080/realms/myrealm",
    "Metadata": "http://localhost:8080/realms/myrealm/.well-known/openid-configuration",
    "ClientId": "oidc-code-pkce",
    // "ClientSecret": "--in user secrets or keyvault--"
  },

The Keycloak server is setup to use the standard settings. You could improve the security of this using token exchange or further supported specifications from Keycloak and ASP.NET Core.

Notes:

Using OpenIddict and ASP.NET Core to federate to further identity providers, it is really easy to support best practice application security and also integrate any third party identity systems without surprises. Having full control of your identity provider is a good thing and by using federation, you do not need to manage the user accounts. This can be fully implemented on the client system. If the application requires strong MFA like FIDO2, this can also be easily implemented in ASP.NET Core. Using some of the cloud solution IDPs prevents you implementing strong application security. These cloud systems do provide excellent user accounting and it would be nice to use this and combine this with a top identity provider.

If implementing a product which needs to support multiple different identity providers from different clients, then you should implement the identity provider as part of your solution context and federate to the client systems.

Links

https://documentation.openiddict.com/

https://github.com/openiddict/openiddict-core

https://docs.microsoft.com/en-us/java/openjdk/download

https://github.com/tuxiem/AspNetCore-keycloak

https://wjw465150.gitbooks.io/keycloak-documentation/content/server_installation/topics/network/https.html

https://www.keycloak.org/documentation.html

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity



One comment

  1. […] Implement an OpenIddict identity provider using ASP.NET Core Identity with Keycloak federation (Damien Bowden) […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: