56

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;

enter image description here

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

Xaruth
  • 3,968
  • 3
  • 17
  • 24
Golda
  • 3,449
  • 10
  • 31
  • 62
  • Well, This link https://stackoverflow.com/questions/21404935/mvc-5-access-claims-identity-user-data/21405315 Saved my life :). – sapana Mar 21 '19 at 05:16

2 Answers2

90

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();
hutchonoid
  • 31,459
  • 14
  • 91
  • 100
  • Still I didn't get the answer. can you please check the update in the above question? I have described the issue. – Golda Mar 07 '14 at 10:19
  • @Golda Hi, the open debug window should be looking at what is in Claims, can you open that one instead? – hutchonoid Mar 07 '14 at 10:27
  • can you please check my question update again. Still i couldn't get the value. – Golda Mar 07 '14 at 11:24
  • @Golda I have re-arranged the answer, try running the retrieval straight after setting it. The debug window is correct, the claim data is there. It isn't caching your old code is it, where you weren't setting the Thread.CurrentPrincipal = claimsPrincpal? – hutchonoid Mar 07 '14 at 12:01
  • I have added Thread.CurrentPrincipal = claimsPrincipal; in the login action. I have updated the Question again. Can you check it please. – Golda Mar 07 '14 at 12:21
  • @Golda I do not understand, the Claims are there in your debug window. I can see them clearly. – hutchonoid Mar 07 '14 at 12:47
  • 1
    Its working. var UserID = principal.Claims.Where(c => c.Type == ClaimTypes.Sid).Select(c => c.Value).SingleOrDefault(); After added .SingleOrDefault() it started working. – Golda Mar 11 '14 at 09:44
  • @Golda Nice one, that had me puzzled. I'll add that to the answer. :) – hutchonoid Mar 11 '14 at 09:50
  • Good stuff. Slight typo in code: claimsPrincpal -> claimsPrincipal code block: 1, line: 7 – Dave Jellison Nov 05 '14 at 00:12
  • 1
    @DaveJellison Thanks, well spotted. No one has noticed that. Updated now. – hutchonoid Nov 05 '14 at 16:45
  • How can I add contacts claim to get contacts of the logged in user? – 3 rules Sep 26 '16 at 14:30
43

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();
Ogglas
  • 38,157
  • 20
  • 203
  • 266