5

I make asp.net web api project.
Client program is winform use HttpClient.
I assign user language to claims when user log in.

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
    .......
    var identity = new ClaimsIdentity(context.Options.AuthenticationType);
                identity.AddClaim(new Claim("UserId", context.UserName));
                identity.AddClaim(new Claim("role", "user"));
                identity.AddClaim(new Claim("Language", forms["language"]));
    context.Validated(identity);
   ......
}

I need to change language of claims runtime. So i make change language api.

    [HttpGet]
    [APIAuthorize]
    public HttpResponseMessage ChangeLanguage(Language language)
    {
        User.AddUpdateClaim("Language", language.ToString());

        return Request.CreateResponse<IResult>(HttpStatusCode.OK, "OK");
    }

and make ClaimsIdentity extension.

public static class ClaimsIdentityExtensions
{
    public static void AddUpdateClaim(this IPrincipal currentPrincipal, string key, string value)
    {
        var identity = new ClaimsIdentity(currentPrincipal.Identity);            
        // check for existing claim and remove it
        var existingClaim = identity.FindFirst(key);
        if (existingClaim != null)
            identity.RemoveClaim(existingClaim);
        // add new claim
        identity.AddClaim(new Claim(key, value));

        var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
        authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(new ClaimsPrincipal(identity), new AuthenticationProperties() { IsPersistent = true });                                 

        HttpContext.Current.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ExternalBearer);
        HttpContext.Current.GetOwinContext().Authentication.SignIn(new AuthenticationProperties() { IsPersistent = true }, identity);

        ClaimsPrincipal principal = Thread.CurrentPrincipal as ClaimsPrincipal;
        if (principal != null)
        {
            identity = principal.Identities.ElementAt(0);
            var old = identity.FindFirst(key);
            if (old != null)
                identity.RemoveClaim(old);

            identity.AddClaim(new Claim(key, value));
        }
    }

    public static string GetClaimValue(this IPrincipal currentPrincipal, string key)
    {
        var identity = currentPrincipal.Identity as ClaimsIdentity;
        if (identity == null)
            return null;

        var claim = identity.Claims.First(c => c.Type == key);
        return claim.Value;
    }
}

then client call "ChangeLanguage" api

    [HttpGet]
    [APIAuthorize]
    public HttpResponseMessage ChangeLanguage(Language language)
    {
        User.AddUpdateClaim("Language", language.ToString());

        return Request.CreateResponse<IResult>(HttpStatusCode.OK, "OK");
    }

but constructor of controller called next time
claims not updated.

    public MyController()
    {
        var user = this.User.Identity as ClaimsIdentity;
        if (user.IsAuthenticated)
        {
            // language not changed
            var language = User.GetClaimValue("Language");
        }
    }

How can i change claims? Sorry my english is terrible.

Thank you

duloveme
  • 61
  • 6

0 Answers0