Supporting both Local and Windows Authentication in ASP.NET Core MVC using IdentityServer4

This article shows how to setup an ASP.NET Core MVC application to support both users who can login in with a local login account, solution specific, or use a windows authentication login. The identity created from the windows authentication could then be allowed to do different tasks, for example administration, or a user from the local authentication could be used for guest accounts, etc. To do this, IdentityServer4 is used to handle the authentication. The ASP.NET Core MVC application uses the OpenID Connect Hybrid Flow.

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

Posts in this series:

Setting up the STS using IdentityServer4

The STS is setup using the IdentityServer4 dotnet templates. Once installed, the is4aspid template was used to create the application from the command line.

The windows authentication is activated in the launchSettings.json. To setup the windows authentication for the deployment, refer to the Microsoft Docs.

{
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "https://localhost:44364/",
      "sslPort": 44364
    }
  },

The OpenID Connect Hybrid Flow was then configured for the client application.

new Client
{
	ClientId = "hybridclient",
	ClientName = "MVC Client",

	AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
	ClientSecrets = { new Secret("hybrid_flow_secret".Sha256()) },

	RedirectUris = { "https://localhost:44381/signin-oidc" },
	FrontChannelLogoutUri = "https://localhost:44381/signout-oidc",
	PostLogoutRedirectUris = { "https://localhost:44381/signout-callback-oidc" },

	AllowOfflineAccess = true,
	AllowedScopes = { "openid", "profile", "offline_access",  "scope_used_for_hybrid_flow" }
}

ASP.NET Core MVC Hybrid Client

The ASP.NET Core MVC application is configured to authenticate using the STS server, and to save the tokens in a cookie. The AddOpenIdConnect method configures the OIDC Hybrid client, which must match the settings in the IdentityServer4 application.

The TokenValidationParameters MUST be used, to set the NameClaimType property, otherwise the User.Identity.Name property will be null. This value is returned in the ‘name’ claim, which is not the default.

services.AddAuthentication(options =>
{
	options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
	options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
	options.SignInScheme = "Cookies";
	options.Authority = stsServer;
	options.RequireHttpsMetadata = true;
	options.ClientId = "hybridclient";
	options.ClientSecret = "hybrid_flow_secret";
	options.ResponseType = "code id_token";
	options.GetClaimsFromUserInfoEndpoint = true;
	options.Scope.Add("scope_used_for_hybrid_flow");
	options.Scope.Add("profile");
	options.Scope.Add("offline_access");
	options.SaveTokens = true;
	// Set the correct name claim type
	options.TokenValidationParameters = new TokenValidationParameters
	{
		NameClaimType = "name"
	};
});

Then all controllers can be secured using the Authorize attribute. The anti forgery cookie should also be used, because the application uses cookies to store the tokens.

[Authorize]
public class HomeController : Controller
{

Displaying the login type in the ASP.NET Core Client

Then application then displays the authentication type in the home view. To do this, a requireWindowsProviderPolicy policy is defined, which requires that the identityprovider claim has the value Windows. The policy is added using the AddAuthorization method options.

var requireWindowsProviderPolicy = new AuthorizationPolicyBuilder()
 .RequireClaim("http://schemas.microsoft.com/identity/claims/identityprovider", "Windows")
 .Build();

services.AddAuthorization(options =>
{
	options.AddPolicy(
	  "RequireWindowsProviderPolicy", 
	  requireWindowsProviderPolicy
	);
});

The policy can then be used in the cshtml view.

@using Microsoft.AspNetCore.Authorization
@inject IAuthorizationService AuthorizationService
@{
    ViewData["Title"] = "Home Page";
}

<br />

@if ((await AuthorizationService.AuthorizeAsync(User, "RequireWindowsProviderPolicy")).Succeeded)
{
    <p>Hi Admin, you logged in with an internal Windows account</p>
}
else
{
    <p>Hi local user</p>

}

Both applications can then be started. The client application is redirected to the STS server and the user can login with either the Windows authentication, or a local account.

The text in the client application is displayed depending on the Identity returned.

Identity created for the Windows Authentication:

Local Identity:

Next Steps

The application now works for Windows authentication, or a local account authentication. The authorization now needs to be set, so that the different types have different claims. The identities returned from the Windows Authentication will have different claims, to the identities returned form the local logon, which will be used for guest accounts.

Links:

https://docs.microsoft.com/en-us/aspnet/core/security/authorization/views?view=aspnetcore-2.1&tabs=aspnetcore2x

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/?view=aspnetcore-2.1

https://mva.microsoft.com/en-US/training-courses/introduction-to-identityserver-for-aspnet-core-17945

https://stackoverflow.com/questions/34951713/aspnet5-windows-authentication-get-group-name-from-claims/34955119

https://github.com/IdentityServer/IdentityServer4.Templates

https://docs.microsoft.com/en-us/iis/configuration/system.webserver/security/authentication/windowsauthentication/

Advertisements

4 comments

  1. […] on April 15, 2018by admin submitted by /u/mycall [link] [comments] No comments […]

  2. […] Supporting both Local and Windows Authentication in ASP.NET Core MVC using IdentityServer4 (Damien Bowden) […]

  3. Michael Paine · · Reply

    Should the 44318 port instead be port 44364?

    1. Hi Michael, no only the STS application has the windows auth activated.

      Greetings Damien

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 )

Google+ photo

You are commenting using your Google+ 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

%d bloggers like this: