2

I implemented the sample solution using .NET, Okta and ITFOXTEC found here. Everything worked fine. I then tried to integrate this solution into our main codebase which is also using ASP.NET Identity. Once I added the identity configuration, it seems whatever identity that was created by ITFoxtec was overwritten (none of the SAML claims are present after login). I reproduced the issue by adding the following to the Startup.cs in the sample solution above.

       services.AddDbContext<ApplicationDbContext>();

       services.AddIdentity<IdentityUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();

I'm hoping to use both SAML and Identity framework in the same solution, but not sure they are compatible.

DarkBee
  • 16,592
  • 6
  • 46
  • 58

2 Answers2

0

I'm not sure it this is possible, I have never tried it. However, I think it is possible.

It sounds like the received SAML 2.0 identity is overridden and thereby also the claims. Please share your findings if you succeed.

Anders Revsgaard
  • 3,636
  • 1
  • 9
  • 25
0

I know this is a little late but we have got SAML working with ASP.NET Identity in an ASP.NET MVC Core 6 application. We used the same sample mentioned above and did this in the CreateClaimsPrincipal method of the ClaimsTransform class:

    using System.Security.Claims;
    using Microsoft.AspNetCore.Identity;
    using ITfoxtec.Identity.Saml2.Claims;

    ...

    // add the ASP.NET Identity roles as Claims
    var idClaim = GetClaim(incomingPrincipal, Saml2ClaimTypes.NameId);
    if (idClaim != null)
    {
        IdentityUser identityUser = await userManager.FindByEmailAsync(idClaim.Value);
        if (identityUser != null)
        {
            foreach (var r in await userManager.GetRolesAsync(identityUser))
            {
                claims.Add(new Claim(type: ClaimTypes.Role, value: r));
            }
        }
    }

We probably should make ClaimsTransform non static and inject the UserManager<IdentityUser> userManager but right now it's being passed in as a parameter from the call in AuthController.

After this normal ASP.NET Identity stuff worked. Authorize attributes on Controllers and Actions: [Authorize(Roles = "Identity Role 1, Identity Role 2")]

And User.IsInRole("Identity Role 1") checks in code and .cshtml

And in program.cs we do the SAML configuration last - just before var app = builder.Build();

The only other thing that you might want to do is prevent access to some/all of the default Identity pages. We did this in program.cs to prevent users accessing the Registration page but you can also scaffold the identity pages and edit them as Microsoft suggests here.

app.UseEndpoints(endpoints =>
{    
    endpoints.MapGet("/Identity/Account/Register", context => Task.Factory.StartNew(() => context.Response.Redirect("/", true, true)));
    endpoints.MapPost("/Identity/Account/Register", context => Task.Factory.StartNew(() => context.Response.Redirect("/", true, true)));
}
Ben wood
  • 21
  • 1
  • 5