简体   繁体   中英

ASP.NET Core authenticating with Azure Active Directory and persisting custom Claims across requests

I have a default ASP.NET Core website created within Visual Studio 2017. I have chosen to authenticate using an Azure Active Directory. I run the site and can successfully login using an account in the Active Directory.

I can retrieve Claim information provided by Active Directory, eg by calling the following line I get the 'name'.

User.Claims.FirstOrDefault(c => c.Type == "name")?.Value;

I want to add a custom claim - CompanyId = 123456 for the logged in user. I'm able to add a custom claim however it is only available on the page where the claim is set.

Claim claim = new Claim("CompanyId", "123456", ClaimValueTypes.String);
((ClaimsIdentity)User.Identity).AddClaim(claim);

My understanding is that I somehow need to update the token that has been issued by Active Directory or set the claim before the token is issued. I'm unsure how to do this.

I suspect this needs to be done in the AccountController at SignIn()

// GET: /Account/SignIn
[HttpGet]
public IActionResult SignIn()
{
    return Challenge(
            new AuthenticationProperties { RedirectUri = "/" }, OpenIdConnectDefaults.AuthenticationScheme);
}

I've read numerous articles and samples about this scenario (including https://github.com/ahelland/AADGuide-CodeSamples/tree/master/ClaimsWebApp ) however have not managed to solve how to persist the Claim across requests.

I have successfully managed to persist custom Claims using ASP.NET Identity as the Authentication Provider, but this appears to be because the custom Claim is saved to the database..

OnTokenValidated offers you the chance to modify the ClaimsIdentity obtained from the incoming token , code below is for your reference :

private Task TokenValidated(TokenValidatedContext context)
{
    Claim claim = new Claim("CompanyId", "123456", ClaimValueTypes.String);
    (context.Ticket.Principal.Identity as ClaimsIdentity).AddClaim(claim);

    return Task.FromResult(0);
}

Setting the OpenIdConnectEvents :

Events = new OpenIdConnectEvents
{
    OnRemoteFailure = OnAuthenticationFailed,
    OnAuthorizationCodeReceived = OnAuthorizationCodeReceived,

    OnTokenValidated = TokenValidated
}

Then in controller using :

var companyId=  User.Claims.FirstOrDefault(c => c.Type == "CompanyId")?.Value;

For those who would like more detail, the code provided is placed in Startup.cs

In the Configure method add/edit:

app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
{
    ClientId = Configuration["Authentication:AzureAd:ClientId"],
    Authority = Configuration["Authentication:AzureAd:AADInstance"] + Configuration["Authentication:AzureAd:TenantId"],
    CallbackPath = Configuration["Authentication:AzureAd:CallbackPath"],
    Events = new OpenIdConnectEvents
    {
        OnTokenValidated = TokenValidated
    }
});

The private Task TokenValidated method is in the body of Startup.cs

The following sample is a good reference. https://github.com/Azure-Samples/active-directory-dotnet-webapp-openidconnect-aspnetcore-v2/blob/master/WebApp-OpenIDConnect-DotNet/Startup.cs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM