Access Claim values in controller in MVC 5

2019-01-22 11:13发布

问题:

I have used OWIN authentication in my application.

Login Action

var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, result.UserFirstName));            
claims.Add(new Claim(ClaimTypes.Sid, result.UserID.ToString()));
var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);

I want to access the UserName and UserID from different action. How can I access the values which is added in the claims?

Update I have tried

var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, result.UserFirstName + " " + result.UserLastName));            
claims.Add(new Claim(ClaimTypes.Sid, result.UserIDNumber.ToString()));
var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
var authenticationManager = Request.GetOwinContext().Authentication;
authenticationManager.SignIn(identity);

var claimsPrincipal = new ClaimsPrincipal(identity);
Thread.CurrentPrincipal = claimsPrincipal;

I can view the values inside the quick window. But even though I couldn't access the value. How to get the value?

回答1:

You need to set your Thread.CurrentPrincipal after login i.e.

var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, result.UserFirstName));            
claims.Add(new Claim(ClaimTypes.Sid, result.UserID.ToString()));
var identity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
var claimsPrincipal = new ClaimsPrincipal(identity);
// Set current principal
Thread.CurrentPrincipal = claimsPrincipal;

Then the following will retrieve the values.

//Get the current claims principal
var identity = (ClaimsPrincipal)Thread.CurrentPrincipal;

// Get the claims values
var name = identity.Claims.Where(c => c.Type == ClaimTypes.Name)
                   .Select(c => c.Value).SingleOrDefault();
var sid = identity.Claims.Where(c => c.Type == ClaimTypes.Sid)
                   .Select(c => c.Value).SingleOrDefault();


回答2:

Here is another example, with custom claim types as well:

Login:

var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, user.Name, ClaimValueTypes.String),
    new Claim(ClaimTypes.Email, user.Email ?? string.Empty, ClaimValueTypes.Email),
    new Claim(ClaimTypes.PrimarySid, user.Id.ToString(), ClaimValueTypes.Integer),
    new Claim(CustomClaimTypes.SalesId, user.SalesId.ToString(), ClaimValueTypes.Integer)
};

var claimsIdentity = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(claimsIdentity);

Custom claims:

public static class CustomClaimTypes
{
    public const string SalesId = "SalesId";
}

Extension methods:

public static class IdentityExtensions
{
    public static int GetSalesId(this IIdentity identity)
    {
        ClaimsIdentity claimsIdentity = identity as ClaimsIdentity;
        Claim claim = claimsIdentity?.FindFirst(CustomClaimTypes.SalesId);

        if (claim == null)
            return 0;

        return int.Parse(claim.Value);
    }

    public static string GetName(this IIdentity identity)
    {
        ClaimsIdentity claimsIdentity = identity as ClaimsIdentity;
        Claim claim = claimsIdentity?.FindFirst(ClaimTypes.Name);

        return claim?.Value ?? string.Empty;
    }
}

Can then be accessed like this:

User.Identity.GetSalesId();
User.Identity.GetName();