Be Sociable, Share!

Tweet



Email

WhatsApp



This is the fifth part of Building Simple Membership system using ASP.NET Identity 2.1, ASP.NET Web API 2.2 and AngularJS. The topics we’ll cover are:

The source code for this tutorial is available on GitHub.

ASP.NET Web API Claims Authorization with ASP.NET Identity 2.1

In the previous post we have implemented a finer grained way to control authorization based on the Roles assigned for the authenticated user, this was done by assigning users to a predefined Roles in our system and then attributing the protected controllers or actions by the [Authorize(Roles = “Role(s) Name”)] attribute.

Using Roles Based Authorization for controlling user access will be efficient in scenarios where your Roles do not change too much and the users permissions do not change frequently.

In some applications controlling user access on system resources is more complicated, and having users assigned to certain Roles is not enough for managing user access efficiently, you need more dynamic way to to control access based on certain information related to the authenticated user, this will lead us to control user access using Claims, or in another word using Claims Based Authorization.

But before we dig into the implementation of Claims Based Authorization we need to understand what Claims are!

Note: It is not mandatory to use Claims for controlling user access, if you are happy with Roles Based Authorization and you have limited number of Roles then you can stick to this.

What is a Claim?

Claim is a statement about the user makes about itself, it can be user name, first name, last name, gender, phone, the roles user assigned to, etc… Yes the Roles we have been looking at are transformed to Claims at the end, and as we saw in the previous post; in ASP.NET Identity those Roles have their own manager (ApplicationRoleManager) and set of APIs to manage them, yet you can consider them as a Claim of type Role.

As we saw before, any authenticated user will receive a JSON Web Token (JWT) which contains a set of claims inside it, what we’ll do now is to create a helper end point which returns the claims encoded in the JWT for an authenticated user.

To do this we will create a new controller named “ClaimsController” which will contain a single method responsible to unpack the claims in the JWT and return them, to do this add new controller named “ClaimsController” under folder Controllers and paste the code below:

[RoutePrefix("api/claims")] public class ClaimsController : BaseApiController { [Authorize] [Route("")] public IHttpActionResult GetClaims() { var identity = User.Identity as ClaimsIdentity; var claims = from c in identity.Claims select new { subject = c.Subject.Name, type = c.Type, value = c.Value }; return Ok(claims); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [ RoutePrefix ( "api/claims" ) ] public class ClaimsController : BaseApiController { [ Authorize ] [ Route ( "" ) ] public IHttpActionResult GetClaims ( ) { var identity = User . Identity as ClaimsIdentity ; var claims = from c in identity . Claims select new { subject = c . Subject . Name , type = c . Type , value = c . Value } ; return Ok ( claims ) ; } }

The code we have implemented above is straight forward, we are getting the Identity of the authenticated user by calling “User.Identity” which returns “ClaimsIdentity” object, then we are iterating over the IEnumerable Claims property and return three properties which they are (Subject, Type, and Value).

To execute this endpoint we need to issue HTTP GET request to the end point “http://localhost/api/claims” and do not forget to pass a valid JWT in the Authorization header, the response for this end point will contain the below JSON object:

[ { "subject": "Hamza", "type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", "value": "cd93945e-fe2c-49c1-b2bb-138a2dd52928" }, { "subject": "Hamza", "type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "value": "Hamza" }, { "subject": "Hamza", "type": "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "value": "ASP.NET Identity" }, { "subject": "Hamza", "type": "AspNet.Identity.SecurityStamp", "value": "a77594e2-ffa0-41bd-a048-7398c01c8948" }, { "subject": "Hamza", "type": "iss", "value": "http://localhost:59822" }, { "subject": "Hamza", "type": "aud", "value": "414e1927a3884f68abc79f7283837fd1" }, { "subject": "Hamza", "type": "exp", "value": "1427744352" }, { "subject": "Hamza", "type": "nbf", "value": "1427657952" } ] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 [ { "subject" : "Hamza" , "type" : "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier" , "value" : "cd93945e-fe2c-49c1-b2bb-138a2dd52928" } , { "subject" : "Hamza" , "type" : "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" , "value" : "Hamza" } , { "subject" : "Hamza" , "type" : "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider" , "value" : "ASP.NET Identity" } , { "subject" : "Hamza" , "type" : "AspNet.Identity.SecurityStamp" , "value" : "a77594e2-ffa0-41bd-a048-7398c01c8948" } , { "subject" : "Hamza" , "type" : "iss" , "value" : "http://localhost:59822" } , { "subject" : "Hamza" , "type" : "aud" , "value" : "414e1927a3884f68abc79f7283837fd1" } , { "subject" : "Hamza" , "type" : "exp" , "value" : "1427744352" } , { "subject" : "Hamza" , "type" : "nbf" , "value" : "1427657952" } ]

As you noticed from the response above, all the claims contain three properties, and those properties represents the below:

Subject : Represents the identity which those claims belongs to, usually the value for the subject will contain the unique identifier for the user in the system (Username or Email).

: Represents the identity which those claims belongs to, usually the value for the subject will contain the unique identifier for the user in the system (Username or Email). Type : Represents the type of the information contained in the claim.

: Represents the type of the information contained in the claim. Value: Represents the claim value (information) about this claim.

Now to have better understanding of what type of those claims mean let’s take a look the table below:

Subject Type Value Notes Hamza nameidentifier cd93945e-fe2c-49c1-b2bb-138a2dd52928 Unique User Id generated from Identity System Hamza name Hamza Unique Username Hamza identityprovider ASP.NET Identity How user has been authenticated using ASP.NET Identity Hamza SecurityStamp a77594e2-ffa0-41bd-a048-7398c01c8948 Unique Id which stays the same until any security related attribute change, i.e. change user password Hamza iss http://localhost:59822 Issuer of the Access Token (Authz Server) Hamza aud 414e1927a3884f68abc79f7283837fd1 For which system this token is generated Hamza exp 1427744352 Expiry time for this access token (Epoch) Hamza nbf 1427657952 When this token is issued (Epoch)

After we have briefly described what claims are, we want to see how we can use them to manage user assess, in this post I will demonstrate three ways of using the claims as the below:

Assigning claims to the user on the fly based on user information. Creating custom Claims Authorization attribute. Managing user claims by using the “ApplicationUserManager” APIs.

Method 1: Assigning claims to the user on the fly

Let’s assume a fictional use case where our API will be used in an eCommerce website, where certain users have the ability to issue refunds for orders if there is incident happen and the customer is not happy.

So certain criteria should be met in order to grant our users the privileges to issue refunds, the users should have been working for the company for more than 90 days, and the user should be in “Admin”Role.

To implement this we need to create a new class which will be responsible to read authenticated user information, and based on the information read, it will create a single claim or set of claims and assign then to the user identity.

If you recall from the first post of this series, we have extended the “ApplicationUser” entity and added a property named “JoinDate” which represent the hiring date of the employee, based on the hiring date, we need to assign a new claim named “FTE” (Full Time Employee) for any user who has worked for more than 90 days. To start implementing this let’s add a new class named “ExtendedClaimsProvider” under folder “Infrastructure” and paste the code below:

public static class ExtendedClaimsProvider { public static IEnumerable<Claim> GetClaims(ApplicationUser user) { List<Claim> claims = new List<Claim>(); var daysInWork = (DateTime.Now.Date - user.JoinDate).TotalDays; if (daysInWork > 90) { claims.Add(CreateClaim("FTE", "1")); } else { claims.Add(CreateClaim("FTE", "0")); } return claims; } public static Claim CreateClaim(string type, string value) { return new Claim(type, value, ClaimValueTypes.String); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public static class ExtendedClaimsProvider { public static IEnumerable < Claim > GetClaims ( ApplicationUser user ) { List < Claim > claims = new List < Claim > ( ) ; var daysInWork = ( DateTime . Now . Date - user . JoinDate ) . TotalDays ; if ( daysInWork > 90 ) { claims . Add ( CreateClaim ( "FTE" , "1" ) ) ; } else { claims . Add ( CreateClaim ( "FTE" , "0" ) ) ; } return claims ; } public static Claim CreateClaim ( string type , string value ) { return new Claim ( type , value , ClaimValueTypes . String ) ; } }

The implementation is simple, the “GetClaims” method will take ApplicationUser object and returns a list of claims. Based on the “JoinDate” field it will add new claim named “FTE” and will assign a value of “1” if the user has been working for than 90 days, and a value of “0” if the user worked for less than this period. Notice how I’m using the method “CreateClaim” which returns a new instance of the claim.

This class can be used to enforce creating custom claims for the user based on the information related to her, you can add as many claims as you want here, but in our case we will add only a single claim.

Now we need to call the method “GetClaims” so the “FTE” claim will be associated with the authenticated user identity, to do this open class “CustomOAuthProvider” and in method “GrantResourceOwnerCredentials” add the highlighted line (line 7) as the code snippet below:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { //Code removed for brevity ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, "JWT"); oAuthIdentity.AddClaims(ExtendedClaimsProvider.GetClaims(user)); var ticket = new AuthenticationTicket(oAuthIdentity, null); context.Validated(ticket); } 1 2 3 4 5 6 7 8 9 10 11 12 13 public override async Task GrantResourceOwnerCredentials ( OAuthGrantResourceOwnerCredentialsContext context ) { //Code removed for brevity ClaimsIdentity oAuthIdentity = await user . GenerateUserIdentityAsync ( userManager , "JWT" ) ; oAuthIdentity . AddClaims ( ExtendedClaimsProvider . GetClaims ( user ) ) ; var ticket = new AuthenticationTicket ( oAuthIdentity , null ) ; context . Validated ( ticket ) ; }

Notice how the established claims identity object “oAuthIdentity” has a method named “AddClaims” which accepts IEnumerable object of claims, now the new “FTE” claim is assigned to the authenticated user, but this is not enough to satisfy the criteria needed to issue the fictitious refund on orders, we need to make sure that the user is in “Admin” Role too.

To implement this we’ll create a new Role on the fly based on the claims assigned for the user, in other words we’ll create Roles from the Claims user assigned to, this Role will be named “IncidentResolvers”. And as we stated in the beginning of this post, the Roles eventually are considered as a Claim of type Role.

To do this add new class named “RolesFromClaims” under folder “Infrastructure” and paste the code below:

public class RolesFromClaims { public static IEnumerable<Claim> CreateRolesBasedOnClaims(ClaimsIdentity identity) { List<Claim> claims = new List<Claim>(); if (identity.HasClaim(c => c.Type == "FTE" && c.Value == "1") && identity.HasClaim(ClaimTypes.Role, "Admin")) { claims.Add(new Claim(ClaimTypes.Role, "IncidentResolvers")); } return claims; } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class RolesFromClaims { public static IEnumerable < Claim > CreateRolesBasedOnClaims ( ClaimsIdentity identity ) { List < Claim > claims = new List < Claim > ( ) ; if ( identity . HasClaim ( c = > c . Type == "FTE" && c . Value == "1" ) && identity . HasClaim ( ClaimTypes . Role , "Admin" ) ) { claims . Add ( new Claim ( ClaimTypes . Role , "IncidentResolvers" ) ) ; } return claims ; } }

The implementation is self explanatory, we have created a method named “CreateRolesBasedOnClaims” which accepts the established identity object and returns a list of claims.

Inside this method we will check that the established identity for the authenticated user has a claim of type “FTE” with value “1”, as well that the identity contains a claim of type “Role” with value “Admin”, if those 2 conditions are met then; we will create a new claim of Type “Role” and give it a value of “IncidentResolvers”.

Last thing we need to do here is to assign this new set of claims to the established identity, so to do this open class “CustomOAuthProvider” again and in method “GrantResourceOwnerCredentials” add the highlighted line (line 9) as the code snippet below:

public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { //Code removed for brevity ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, "JWT"); oAuthIdentity.AddClaims(ExtendedClaimsProvider.GetClaims(user)); oAuthIdentity.AddClaims(RolesFromClaims.CreateRolesBasedOnClaims(oAuthIdentity)); var ticket = new AuthenticationTicket(oAuthIdentity, null); context.Validated(ticket); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public override async Task GrantResourceOwnerCredentials ( OAuthGrantResourceOwnerCredentialsContext context ) { //Code removed for brevity ClaimsIdentity oAuthIdentity = await user . GenerateUserIdentityAsync ( userManager , "JWT" ) ; oAuthIdentity . AddClaims ( ExtendedClaimsProvider . GetClaims ( user ) ) ; oAuthIdentity . AddClaims ( RolesFromClaims . CreateRolesBasedOnClaims ( oAuthIdentity ) ) ; var ticket = new AuthenticationTicket ( oAuthIdentity , null ) ; context . Validated ( ticket ) ; }

Now all the new claims which created on the fly are assigned to the established identity and once we call the method “context.Validated(ticket)”, all claims will get encoded in the JWT token, so to test this out let’s add fictitious controller named “OrdersController” under folder “Controllers” as the code below:

[RoutePrefix("api/orders")] public class OrdersController : ApiController { [Authorize(Roles = "IncidentResolvers")] [HttpPut] [Route("refund/{orderId}")] public IHttpActionResult RefundOrder([FromUri]string orderId) { return Ok(); } } 1 2 3 4 5 6 7 8 9 10 11 [ RoutePrefix ( "api/orders" ) ] public class OrdersController : ApiController { [ Authorize ( Roles = "IncidentResolvers" ) ] [ HttpPut ] [ Route ( "refund/{orderId}" ) ] public IHttpActionResult RefundOrder ( [ FromUri ] string orderId ) { return Ok ( ) ; } }

Notice how we attribute the action “RefundOrder” with [Authorize(Roles = “IncidentResolvers”)] so only authenticated users with claim of type “Role” and has the value of “IncidentResolvers” can access this end point. To test this out you can issue HTTP PUT request to the URI “http://localhost/api/orders/refund/cxy-4456393” with an empty body.

As you noticed from the first method, we have depended on user information to create claims and kept the authorization more dynamic and flexible.

Keep in mind that you can add your access control business logic, and have finer grained control on authorization by implementing this logic into classes “ExtendedClaimsProvider” and “RolesFromClaims”.

Method 2: Creating custom Claims Authorization attribute

Another way to implement Claims Based Authorization is to create a custom authorization attribute which inherits from “AuthorizationFilterAttribute”, this authorize attribute will check directly the claims value and type for the established identity.

To do this let’s add new class named “ClaimsAuthorizationAttribute” under folder “Infrastructure” and paste the code below:

public class ClaimsAuthorizationAttribute : AuthorizationFilterAttribute { public string ClaimType { get; set; } public string ClaimValue { get; set; } public override Task OnAuthorizationAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken) { var principal = actionContext.RequestContext.Principal as ClaimsPrincipal; if (!principal.Identity.IsAuthenticated) { actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized); return Task.FromResult<object>(null); } if (!(principal.HasClaim(x => x.Type == ClaimType && x.Value == ClaimValue))) { actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized); return Task.FromResult<object>(null); } //User is Authorized, complete execution return Task.FromResult<object>(null); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class ClaimsAuthorizationAttribute : AuthorizationFilterAttribute { public string ClaimType { get ; set ; } public string ClaimValue { get ; set ; } public override Task OnAuthorizationAsync ( HttpActionContext actionContext , System . Threading . CancellationToken cancellationToken ) { var principal = actionContext . RequestContext . Principal as ClaimsPrincipal ; if ( ! principal . Identity . IsAuthenticated ) { actionContext . Response = actionContext . Request . CreateResponse ( HttpStatusCode . Unauthorized ) ; return Task . FromResult < object > ( null ) ; } if ( ! ( principal . HasClaim ( x = > x . Type == ClaimType && x . Value == ClaimValue ) ) ) { actionContext . Response = actionContext . Request . CreateResponse ( HttpStatusCode . Unauthorized ) ; return Task . FromResult < object > ( null ) ; } //User is Authorized, complete execution return Task . FromResult < object > ( null ) ; } }

What we’ve implemented here is the following:

Created a new class named “ClaimsAuthorizationAttribute” which inherits from “AuthorizationFilterAttribute” and then override method “OnAuthorizationAsync”.

Defined 2 properties “ClaimType” & “ClaimValue” which will be used as a setters when we use this custom authorize attribute.

Inside method “OnAuthorizationAsync” we are casting the object “actionContext.RequestContext.Principal” to “ClaimsPrincipal” object and check if the user is authenticated.

If the user is authenticated we’ll look into the claims established for this identity if it has the claim type and claim value.

If the identity contains the same claim type and value; then we’ll consider the request authentic and complete the execution, other wist we’ll return 401 unauthorized status.

To test the new custom authorization attribute, we’ll add new method to the “OrdersController” as the code below:

[ClaimsAuthorization(ClaimType="FTE", ClaimValue="1")] [Route("")] public IHttpActionResult Get() { return Ok(); } 1 2 3 4 5 6 [ ClaimsAuthorization ( ClaimType = "FTE" , ClaimValue = "1" ) ] [ Route ( "" ) ] public IHttpActionResult Get ( ) { return Ok ( ) ; }

Notice how we decorated the “Get()” method with the “[ClaimsAuthorization(ClaimType=”FTE”, ClaimValue=”1″)]” attribute, so any user has the claim “FTE” with value “1” can access this protected end point.

Method 3: Managing user claims by using the “ApplicationUserManager” APIs

The last method we want to explore here is to use the “ApplicationUserManager” claims related API to manage user claims and store them in ASP.NET Identity related tables “AspNetUserClaims”.

In the previous two methods we’ve created claims for the user on the fly, but in method 3 we will see how we can add/remove claims for a certain user.

The “ApplicationUserManager” class comes with a set of predefined APIs which makes dealing and managing claims simple, the APIs that we’ll use in this post are listed in the table below:

Method Name Usage AddClaimAsync(id, claim) Create a new claim for specified user id RemoveClaimAsync(id, claim) Remove claim from specified user if claim type and value match GetClaimsAsync(id) Return IEnumerable of claims based on specified user id

To use those APIs let’s add 2 new methods to the “AccountsController”, the first method “AssignClaimsToUser” will be responsible to add new claims for specified user, and the second method “RemoveClaimsFromUser” will remove claims from a specified user as the code below:

[Authorize(Roles = "Admin")] [Route("user/{id:guid}/assignclaims")] [HttpPut] public async Task<IHttpActionResult> AssignClaimsToUser([FromUri] string id, [FromBody] List<ClaimBindingModel> claimsToAssign) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var appUser = await this.AppUserManager.FindByIdAsync(id); if (appUser == null) { return NotFound(); } foreach (ClaimBindingModel claimModel in claimsToAssign) { if (appUser.Claims.Any(c => c.ClaimType == claimModel.Type)) { await this.AppUserManager.RemoveClaimAsync(id, ExtendedClaimsProvider.CreateClaim(claimModel.Type, claimModel.Value)); } await this.AppUserManager.AddClaimAsync(id, ExtendedClaimsProvider.CreateClaim(claimModel.Type, claimModel.Value)); } return Ok(); } [Authorize(Roles = "Admin")] [Route("user/{id:guid}/removeclaims")] [HttpPut] public async Task<IHttpActionResult> RemoveClaimsFromUser([FromUri] string id, [FromBody] List<ClaimBindingModel> claimsToRemove) { if (!ModelState.IsValid) { return BadRequest(ModelState); } var appUser = await this.AppUserManager.FindByIdAsync(id); if (appUser == null) { return NotFound(); } foreach (ClaimBindingModel claimModel in claimsToRemove) { if (appUser.Claims.Any(c => c.ClaimType == claimModel.Type)) { await this.AppUserManager.RemoveClaimAsync(id, ExtendedClaimsProvider.CreateClaim(claimModel.Type, claimModel.Value)); } } return Ok(); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 [ Authorize ( Roles = "Admin" ) ] [ Route ( "user/{id:guid}/assignclaims" ) ] [ HttpPut ] public async Task < IHttpActionResult > AssignClaimsToUser ( [ FromUri ] string id , [ FromBody ] List < ClaimBindingModel > claimsToAssign ) { if ( ! ModelState . IsValid ) { return BadRequest ( ModelState ) ; } var appUser = await this . AppUserManager . FindByIdAsync ( id ) ; if ( appUser == null ) { return NotFound ( ) ; } foreach ( ClaimBindingModel claimModel in claimsToAssign ) { if ( appUser . Claims . Any ( c = > c . ClaimType == claimModel . Type ) ) { await this . AppUserManager . RemoveClaimAsync ( id , ExtendedClaimsProvider . CreateClaim ( claimModel . Type , claimModel . Value ) ) ; } await this . AppUserManager . AddClaimAsync ( id , ExtendedClaimsProvider . CreateClaim ( claimModel . Type , claimModel . Value ) ) ; } return Ok ( ) ; } [ Authorize ( Roles = "Admin" ) ] [ Route ( "user/{id:guid}/removeclaims" ) ] [ HttpPut ] public async Task < IHttpActionResult > RemoveClaimsFromUser ( [ FromUri ] string id , [ FromBody ] List < ClaimBindingModel > claimsToRemove ) { if ( ! ModelState . IsValid ) { return BadRequest ( ModelState ) ; } var appUser = await this . AppUserManager . FindByIdAsync ( id ) ; if ( appUser == null ) { return NotFound ( ) ; } foreach ( ClaimBindingModel claimModel in claimsToRemove ) { if ( appUser . Claims . Any ( c = > c . ClaimType == claimModel . Type ) ) { await this . AppUserManager . RemoveClaimAsync ( id , ExtendedClaimsProvider . CreateClaim ( claimModel . Type , claimModel . Value ) ) ; } } return Ok ( ) ; }

The implementation for both methods is very identical, as you noticed we are only allowing users in “Admin” role to access those endpoints, then we are specifying the UserId and a list of the claims that will be add or removed for this user.

Then we are making sure that user specified exists in our system before trying to do any operation on the user.

In case we are adding a new claim for the user, we will check if the user has the same claim type before trying to add it, add if it exists before we’ll remove this claim and add it again with the new claim value.

The same applies when we try to remove a claim from the user, notice that methods “AddClaimAsync” and “RemoveClaimAsync” will save the claims permanently in our SQL data-store in table “AspNetUserClaims”.

Do not forget to add the “ClaimBindingModel” under folder “Models” which acts as our POCO class when we are sending the claims from our front-end application, the class will contain the code below:

public class ClaimBindingModel { [Required] [Display(Name = "Claim Type")] public string Type { get; set; } [Required] [Display(Name = "Claim Value")] public string Value { get; set; } } 1 2 3 4 5 6 7 8 9 10 public class ClaimBindingModel { [ Required ] [ Display ( Name = "Claim Type" ) ] public string Type { get ; set ; } [ Required ] [ Display ( Name = "Claim Value" ) ] public string Value { get ; set ; } }

There is no extra steps needed in order to pull those claims from the SQL data-store when establishing the user identity, thanks for the method “CreateIdentityAsync” which is responsible to pull all the claims for the user. We have already implemented this and it can be checked by visiting the highlighted LOC.

To test those methods all you need to do is to issue HTTP PUT request to the URI: “http://localhost:59822/api/accounts/user/{UserId}/assignclaims” and “http://localhost:59822/api/accounts/user/{UserId}/removeclaims” as the request images below:

That’s it for now folks about implementing Authorization using Claims.

In the next post we’ll build a simple AngularJS application which connects all those posts together, this post should be interesting 🙂

The source code for this tutorial is available on GitHub.

Follow me on Twitter @tjoudeh

References