Search code examples
asp.net-mvcfederated-identity

Updating claims using Federated Authentication in asp.net mvc


I'm using the FederatedAuthentication class in my MVC project.

To create the cookie I use FederatedAuthentication.SessionAuthenticationModule.CreateSessionCookie(...);, but I can't seem to find a way to update them if the user wants to change for example their first name.

How can I access and update the claims without logging out?


Solution

  • The process is rather quite easy

    1. Get the list of current claims of the ClaimsPrincipal
    2. Remove the claims you want to update
    3. Add new claims
    4. Authenticate like normal, passing the list of claims.

      var claims = FederatedAuthentication.SessionAuthenticationModule
                .ContextSessionSecurityToken.ClaimsPrincipal.Claims.ToList();
      var givenNameClaim = claims.Single(x => x.Type == "given_name");
      var familyNameClaim = claims.Single(x => x.Type == "family_name");
      var timeZoneClaim = claims.Single(x => x.Type == "time_zone_string");
      var newName = new Claim(givenNameClaim.Type.ToString(), model.FirstName, givenNameClaim.ValueType, givenNameClaim.Issuer);
      var familyName = new Claim(familyNameClaim.Type.ToString(), model.LastName, familyNameClaim.ValueType, familyNameClaim.Issuer);
      var timeZone = new Claim(timeZoneClaim.Type.ToString(), model.SelectedTimeZone, timeZoneClaim.ValueType, timeZoneClaim.Issuer);
      UpdateClaims(newName, familyName, timeZone);
      
          public void UpdateClaims(params Claim[] updatedClaims)
      {
          var currentClaims = FederatedAuthentication.SessionAuthenticationModule.ContextSessionSecurityToken.ClaimsPrincipal.Claims.ToList();
          foreach (var claim in updatedClaims)
          {
              currentClaims.Remove(currentClaims.Single(x => x.Type == claim.Type));
              currentClaims.Add(claim);
          }
      
          var principal = new ClaimsPrincipal(new ClaimsIdentity[] { new ClaimsIdentity(currentClaims, "Auth0") });
          var session = FederatedAuthentication.SessionAuthenticationModule.CreateSessionSecurityToken(
              principal,
              null,
              DateTime.UtcNow,
              DateTime.MaxValue.ToUniversalTime(),
              true);
          FederatedAuthentication.SessionAuthenticationModule.AuthenticateSessionSecurityToken(session, true);
      }