Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure AD Claims in IdentityServer4

I have taken this sample from github to attempt to use IdentityServer4 and Azure AD for authentication.

While I have it working and returning a token, it seems that the claims that I would have expected to receive from Azure AD are not included in the token(s) issued through IdentityServer.

It could be that this is intentional and that I have misunderstood this flow, but I was hoping that the roles that a user is assigned through Azure AD (plus the tenant ID and other useful 'bits' from the Azure token) would be able to be included in the tokens issued to the client.

Would anyone be able to shed some light on this for me? I can paste code in here but the link to the github code is pretty much the same as what I am using.

like image 706
Sean Avatar asked Feb 12 '18 17:02

Sean


1 Answers

I was trying to do the same thing, and managed to eventually piece bits together from looking at the IS4 docs, Github and StackOverflow.

You need to configure a new instance of IProfileService (Docs) in order to tell IdentityServer4 which additional claims for a user's identity (obtained from Azure AD in your case) you want to be passed back to the client.

An example might look like this:

public class CustomProfileService : IProfileService
{
  public Task GetProfileDataAsync(ProfileDataRequestContext context)
  {
    // Get the 'upn' claim out from the identity token returned from Azure AD.
    var upnClaim = context.Subject.FindFirst(c => c.Type == ClaimTypes.Upn);

    // Get 'firstname' and 'givenname' claims from the identity token returned from Azure AD.
    var givenNameClaim = context.Subject.FindFirst(c => c.Type == ClaimTypes.GivenName);
    var surNameClaim = context.Subject.FindFirst(c => c.Type == ClaimTypes.Surname);

    // Add the retrieved claims into the token sent from IdentityServer to the client.
    context.IssuedClaims.Add(upnClaim);
    context.IssuedClaims.Add(givenNameClaim);
    context.IssuedClaims.Add(surNameClaim);
  }

  public Task IsActiveAsync(IsActiveContext context)
  {
      context.IsActive = true;
      return Task.CompletedTask;
  }
}

You will then need to register this service in Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddIdentityServer()
            .AddDeveloperSigningCredential()

            // Register the new profile service. 
            .AddProfileService<CustomProfileService>();
}

Finally, inside of your AccountController.cs (within the IdentityServer4 project - I'm assuming you already have this, see here for a starter setup if not), you need to add the following to ExternalLoginCallback():

[HttpGet]
public async Task<IActionResult> ExternalLoginCallback()
{

    //...

    // this allows us to collect any additonal claims or properties
    // for the specific protocols used and store them in the local auth cookie.
    // this is typically used to store data needed for signout from those protocols.
    var additionalLocalClaims = new List<Claim>();

    // ADD THIS LINE TO TELL IS4 TO ADD IN THE CLAIMS FROM AZURE AD OR ANOTHER EXTERNAL IDP.
    additionalLocalClaims.AddRange(claims);

    //...

}

Hope this helps.

like image 167
Connor Goddard Avatar answered Oct 03 '22 04:10

Connor Goddard