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
Examples of IP-STS:
- Azure Active Directory
- ADFS
- Federated Ping
- Okta
- Site Minder
The implementation
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(“Restricted“);
await response.WriteAsync(“Sign Out“);
await response.WriteAsync(“Sign Out Remote“);
await response.WriteAsync(”
Claims:
“);
await WriteTableHeader(response, new string[] { “Claim Type”, “Value” }, context.User.Claims.Select(c => new string[] { c.Type, c.Value }));
});
Related.
Integrate Ws-Federation into Asp.Net
Integrate SAML2 into Asp.Net using Component Space
WS-Federation metadata generation tool
Pingback: Passive STS integration
Pingback: Integrate SAML2 into Asp.Net using Component Space - Wayne Clifford Barker
This helped me a fair amount in getting started with ws-federation with dotnet core. However, I don’t have a federation metadata file and I defined the token endpoint, wrealm, etc. After the security token from my federation provider gets validated, the updated claimsprincipal are not applied to my httpcontext. This causes a circular loop of having my client not be authenticated, requiring the federation server to send an updated security token, which gets validated, then lost. I see that a cookie is getting generated, but it doesn’t appear to get attached to the HttpContext. Any ideas what might be missing
The problem was not in the WS-Federation configuration, it was with the dotnet core Configure call. This link [https://stackoverflow.com/a/58585194/55913] pointed me in the right direction.