Integrate Ws-Federation into .Net Core

By | Sep 18, 2018

To Integrate Ws-Federation into .Net Core is straight forward although the documentation of this topic is really lacking. In the article below I have some code snippets showing how to do the integration.

Add the following NuGet packages. At the time of writing this article this Nuget packages required .net core 2.1.0.

  • Microsoft.AspNetCore.Authentication.Cookies
  • Microsoft.AspNetCore.Authentication.WsFederation

The following code needs to be added to the ConfigureServices method within the Startup.cs file. You can obviously break it out into its own method / class to keep the code cleaner but for example sake I am showing as part of the ConfigureServices method.

To Integrate with a IP-STS you need the following:

  • Realm
  • Issuer of the IP-STS certificate
  • Metadata address to the IP-STS
public void ConfigureServices(IServiceCollection services)
{
services.Configure(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});

services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
}).AddWsFederation(wsFedOptions =>
{
//RP realm - normally this is the client FQDN unless a realm is given to the RP by the STS
wsFedOptions.Wtrealm = "";
//certificate issuer something like 'CN = COMODO RSA Domain Validation Secure Server CA O = COMODO CA Limited L = Salford S = Greater Manchester C = GB'
wsFedOptions.TokenValidationParameters.ValidIssuer = "";
//url to sts metadata
wsFedOptions.MetadataAddress = "https://server/FederationMetadata/2007-06/FederationMetadata.xml";
}).AddCookie(cookieOptions =>
{
cookieOptions.Cookie.Name = "FedAuth"; //the name of the cookie you wish to use
cookieOptions.Cookie.HttpOnly = true; //indicates the cookie can not be accessed by client scripts

cookieOptions.Events = new CookieAuthenticationEvents
{
// event where you can hook in if you need to do aditional validation after the principal has been retrieved from the cookie.
OnValidatePrincipal = AdditionalValidation
};
});

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}

The method below is where you can add validation or extend the principal once its received.

public static async Task AdditionalValidation(CookieValidatePrincipalContext context)
{
if (context != null && context.Request != null)
{
ClaimsPrincipal userPrincipal = context.Principal;

// Add additional validation here or extend the identity of the claims principal here.
}
}

The WS-federation authentication handler will only kick in once access control has been implemented. As an example I added the authorize attribute to the home controller to force a redirect to the IP-STS.

[Authorize]
public class HomeController : Controller
{

Once authenticated the user details can be accessed via the ClaimsPrincipal class or via the HttpContext. Below is just some code as a example.

await WriteHtmlAsync(context.Response, async response =>
{
await response.WriteAsync($"Hello Authenticated User {HtmlEncode(user.Identity.Name)}
");
await response.WriteAsync("<a class="\"btn" href="\"/restricted\"">Restricted</a>");
await response.WriteAsync("<a class="\"btn" href="\"/signout\"">Sign Out</a>");
await response.WriteAsync("<a class="\"btn" href="\"/signout-remote\"">Sign Out Remote</a>");
await response.WriteAsync("
Claims:
");
await WriteTableHeader(response, new string[] { "Claim Type", "Value" }, context.User.Claims.Select(c => new string[] { c.Type, c.Value }));
});

 

Leave a Reply

avatar

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

  Subscribe  
Notify of