ASP.NET Core authenticating with Azure Active Dire

2020-06-22 01:32发布

问题:

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, e.g. 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..

回答1:

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;


回答2:

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