Skip to content

Beware in ASP.NET Core 2.0: Claims transformation might run multiple times

August 30, 2017

In ASP.NET Core, you can add a claims transformation service to your application, as such:

public void ConfigureServices(IServiceCollection services)
{
   services.AddMvc();
   services.AddAuthentication(options=>
   {
      options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
   }).AddCookie();

   services.AddTransient<IClaimsTransformation, ClaimsTransformer>();
}

And then your ClaimsTransformer might look like this:

class ClaimsTransformer : IClaimsTransformation
{
   public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
   {
     ((ClaimsIdentity)principal.Identity).AddClaim(new Claim("now", DateTime.Now.ToString()));
     return Task.FromResult(principal);
   }
}

And that might be fine. But beware that this might be invoked multiple times. If an app has this code (perhaps in different locations in the app which might be likely):

await HttpContext.AuthenticateAsync();
await HttpContext.AuthenticateAsync();

Then each time AuthenticateAsync is called the claims transformer is invoked. So given the above implementation we’d be adding the “now” claim multiple times.

Moral of the story, claims transformation should be more defensive and/or return a new principal, as such:

class ClaimsTransformer : IClaimsTransformation
{
   public Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal)
   {
      var id = ((ClaimsIdentity)principal.Identity);

      var ci = new ClaimsIdentity(id.Claims, id.AuthenticationType, id.NameClaimType, id.RoleClaimType);
      ci.AddClaim(new Claim("now", DateTime.Now.ToString()));

      var cp = new ClaimsPrincipal(ci);

      return Task.FromResult(cp);
   }
}

HTH

 

No comments yet

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: