Search code examples
c#asp.net-mvcclaims-based-identityclaimsasp.net-identity-3

ASP.NET MVC 5 get claims


I use third-party auth nuget instagram package for login and set new claim:

        app.UseInstagramAuthentication(new InstagramAuthenticationOptions
        {
            ClientId = "XXXXXXXXXXXXXXXXXXXXXXXXX",
            ClientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXX",
            Provider = new InstagramAuthenticationProvider()
            {
                OnAuthenticated = (context) =>
                {
                    context.Identity.AddClaim(new Claim("urn::instagram::accesstoken", context.AccessToken));
                    return Task.FromResult(0);
                }
            }

but when I try to get this claim

        var ctx = HttpContext.GetOwinContext();
        ClaimsPrincipal user = ctx.Authentication.User;
        IEnumerable<Claim> claims = user.Claims;

This claim does not exist in the list. Why?


Solution

  • You need to retrieve and store those claims on external login, maybe something like:

    private async Task StoreAuthTokenClaims(ApplicationUser user)
    {
        // Get the claims identity
        ClaimsIdentity claimsIdentity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
    
        if (claimsIdentity != null)
        {
            // Retrieve the existing claims
            var currentClaims = await UserManager.GetClaimsAsync(user.Id);
    
            // Get the list of access token related claims from the identity
            var tokenClaims = claimsIdentity.Claims
                .Where(c => c.Type.StartsWith("urn:tokens:"));
    
            // Save the access token related claims
            foreach (var tokenClaim in tokenClaims)
            {
                if (!currentClaims.Contains(tokenClaim))
                {
                    await UserManager.AddClaimAsync(user.Id, tokenClaim);
                }
            }
        }
    }
    

    And on the ExternalLoginConfirmation method:

    result = await UserManager.AddLoginAsync(user.Id, info.Login);
    if (result.Succeeded)
    {
        await StoreAuthTokenClaims(user);
    
        // Sign in and redirect the user
        await SignInAsync(user, isPersistent: false);
        return RedirectToLocal(returnUrl);
    }
    

    After that, you can retrieve claims like:

    var claimsIdentity = HttpContext.User.Identity as ClaimsIdentity;
    if (claimsIdentity != null)
    {
        var claims = claimsIdentity.Claims;
    }