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)));
}