Claims Transformation and Authorization Policy in ASP.NET Core /MVC 6
Introduction:
Sometimes claims inside a token of authenticated user may not be enough/sufficient for your application to decide whether the authenticated user is authorized or not. There are lot of reasons that you cannot put all claims inside the token (due to confidentiality, size-limitation, performance, etc.). For example, claims part of JWT token is just Base64 string encoded (so putting confidential/secret claims in JWT token does not make any sense). Cookie size limitation may be another reason for you. In this case, you may need to add/transform/remove/update claims by checking database/cache/file/other-token and/or you may need to set some default claims for guest/anonymous user. ASP.NET Core makes these cases very simple to implement by allowing you to transform user's claims after authentication but before authorization. In this post, I will show you an example of claims transformation. I will also show you an example of authorization policy, a new feature of ASP.NET authorization which allows you to define code based policies, for example, you can define authorization policy that will only allow female sex users to execute some operation.
Description:
Note that I am using beta7 at the time of writing. Claims transformation is very easy to add in your application. First we need a class implementing IClaimsTransformer interface,
public class MyClaimsTransformer : IClaimsTransformer { public ClaimsPrincipal Transform(ClaimsPrincipal principal) { return principal; } public virtual Task<ClaimsPrincipal> TransformAsync(ClaimsPrincipal principal) { if (principal.Identity.IsAuthenticated) { // get this from cache or db var country = "Pakistan"; (principal.Identity as ClaimsIdentity).AddClaim(new Claim("Nationality", country)); } return Task.FromResult(principal); } }
Note that at the of writing IClaimsTransformer has only one TransformAsync method (and beta7 version only invoke TransformAsync method). The above method check whether the user is authenticated. If yes then the system will get the user nationality from db or cache and then add it to the user claims. Now we need to register this class in Startup.Configure method,
app.UseClaimsTransformation(o => o.Transformer = new MyClaimsTransformer());
There is also ClaimsTransformer class in newer build that have OnTransform event which we can use rather than implementing IClaimsTransformer interface. Now let's add some authorization policy that will only allow peoples of Pakistan to execute Message action method,
services.ConfigureAuthorization(options => { options.AddPolicy("MustBePakistani", policy => policy.RequireClaim("Nationality", "Pakistan")); });
[Authorize(Policy = "MustBePakistani")] public IActionResult Message() { return Content("Hi Pakistani"); }
The above method will be only executed if authenticated user nationality is Pakistan. You can use the same example by only allowing male sex users to execute an action method. You can read more about authorization policies at https://github.com/aspnet/Announcements/issues/22.
Summary:
ASP.NET Core makes it very easy to add claims tranformation and code based authorization policies. In this article, I showed you an example that how can we use both.