title: Jwt and ASP.NET CORE Authorization AspNetRoleClaims
body: <p>How to implement Jwt token with ASP.NET CORE Authorization AspNetRoleClaims and Angular?</p>
  <p>I have the following default roles (user types) for example:</p>
  <p>Admin (Gerencia)<br />
  User<br />
  Client</p>
  <p>A user that has the claim to viewRoles can add its own roles with custom claims.</p>
  <p>For example<br />
  worker<br />
  claims canViewClients canViewInventory....</p>
  <p>A user that has a claim to view employees and edit them can select from a dropdown the user type has you can see on my image.
  <a href="https://i.stack.imgur.com/lbeFY.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/lbeFY.png" alt="DropDown with user types" /></a></p>
  <p>When the user selects a user type my application auto fills the claims the user can have access to by default. However the user can always uncheck or check different claims the auto fill is only there to save some time. Here is what my checkbox look like visually.</p>
  <p><a href="https://i.stack.imgur.com/RhjeW.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/RhjeW.png" alt="Claims" /></a></p>
  <p>Each checkbox represents a claim.</p>
  <p>To recap</p>
  <ul>
  <li>The user types are not used to authorize endpoints only to visually quickly populate the checkboxes.</li>
  <li>Each checkbox represent a claim.</li>
  </ul>
  <h2>How can I Add claims/policies to my jwt cookie</h2>
  <p>Here are the important parts of my startup.cs file.</p>
  <pre><code>    public class Startup
      {
          public Startup(IConfiguration configuration)
          {
              Configuration = configuration;
          }
  
          public IConfiguration Configuration { get; }
  
          // This method gets called by the runtime. Use this method to add services to the container.
          public void ConfigureServices(IServiceCollection services)
          {
              services.Configure&lt;ApplicationSettings&gt;(Configuration.GetSection(&quot;AppSettings&quot;)); 
  
              services.AddTransient&lt;DatabaseMigrator&gt;();
              services.AddDbContext&lt;erp_colombiaDbContext&gt;(options =&gt; options.UseMySql(
                       Configuration.GetConnectionString(&quot;DefaultConnection&quot;),
                       optionsBuilder =&gt; optionsBuilder.MigrationsAssembly(typeof(DesignTimeDbContextFactory).Assembly.FullName)));
              services.TryAddScoped&lt;UserManager&lt;Employee&gt;&gt;();
              services.TryAddScoped&lt;SignInManager&lt;Employee&gt;&gt;();
  
  
  //Should I add roles/policies here?
              services.AddIdentityCore&lt;Employee&gt;(options =&gt; 
                  options.SignIn.RequireConfirmedAccount = false
              ).AddRoles&lt;Entities.Type&gt;().AddEntityFrameworkStores&lt;erp_colombiaDbContext&gt;();
  
  
  
              //Jwt Authentication
              var key = Encoding.UTF8.GetBytes(&quot;myKey&quot;);
  
              services.Configure&lt;IdentityOptions&gt;(options =&gt;
              {
                  options.Password.RequireDigit = false;
                  options.Password.RequireNonAlphanumeric = false;
                  options.Password.RequireLowercase = false;
                  options.Password.RequireUppercase = false;
                  options.Password.RequiredLength = 4;
              });
  
              services.AddCors();
  
              //Jwt Authentication
  
              services.AddAuthentication(x =&gt;
              {
                  x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                  x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                  x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;                
              }).AddJwtBearer(x =&gt;
              {
                  x.IncludeErrorDetails = true;
                  x.RequireHttpsMetadata = false;
                  x.TokenValidationParameters = new TokenValidationParameters
                  {
                      RequireSignedTokens = true,
                      ValidateIssuerSigningKey = true,
                      IssuerSigningKey = new SymmetricSecurityKey(key),
                      ValidateIssuer = false,
                      ValidateAudience = false,
                      ClockSkew = TimeSpan.Zero
                  };
                  x.Events = new JwtBearerEvents
                  {
                      OnAuthenticationFailed = c =&gt;
                      {
                          // break point here
                          return Task.CompletedTask;
                      },
                  };
              });
  
              services.AddAuthorization(options =&gt;
              {
              options.AddPolicy(&quot;ViewClientsPolicy&quot;,
                  policy =&gt; policy.RequireClaim(&quot;View Clients&quot;));
              });
  
  
              //services.AddControllersWithViews();
              // In production, the Angular files will be served from this directory
              services.AddSpaStaticFiles(configuration =&gt;
              {
                  configuration.RootPath = &quot;ClientApp/dist&quot;;
              });
  
              services.AddMvc();
  
              services.AddSingleton&lt;IHttpContextAccessor, HttpContextAccessor&gt;();
  
              services.AddScoped&lt;IMenuService, MenuService&gt;();
  
  
             //Service for identity user.
              services.AddScoped&lt;IEmployeeService, EmployeeService&gt;();
             //Service for identity role.
              services.AddScoped&lt;ITypeService, TypeService&gt;();
  
              services.AddScoped&lt;IGeneralConfigurationService, GeneralConfigurationService&gt;();
              services.AddScoped&lt;IComponentLocationService, ComponentLocationService&gt;();
              services.AddScoped&lt;INewsService, NewsService&gt;();
              services.AddScoped&lt;INewsCategoryService, NewsCategoryService&gt;();
              services.AddScoped&lt;INewsCategoriesService, NewsCategoriesService&gt;();
              services.AddScoped&lt;IExternalLinksService, ExternalLinksService&gt;();
              services.AddScoped&lt;IClientService, ClientService&gt;();
              services.AddScoped&lt;ISupplierService, SupplierService&gt;();
              services.AddScoped&lt;IContactService, ContactService&gt;();
              services.AddScoped&lt;IUserTypeService, UserTypeService&gt;();
              services.AddScoped&lt;IComponentService, ComponentService&gt;();
              services.AddScoped&lt;IFamilyService, FamilyService&gt;();
  
              services.AddScoped&lt;IContractMenuService, ContractMenuService&gt;();
              services.AddScoped&lt;IContractService, ContractService&gt;();
  
              services.AddScoped&lt;IHolidayService, HolidayService&gt;();
              services.AddScoped&lt;IExpeditionService, ExpeditionService&gt;();
  
              services.AddScoped&lt;IKanbanService, KanbanService&gt;();
  
          }
  
          // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
          public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
          {
              if (env.IsDevelopment())
              {
                  app.UseDeveloperExceptionPage();
              }
              else
              {
                  app.UseExceptionHandler(&quot;/Error&quot;);
                  // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                  app.UseHsts();
              }
  
              app.UseHttpsRedirection();
              app.UseStaticFiles();
              if (!env.IsDevelopment())
              {
                  app.UseSpaStaticFiles();
              }
  
              app.UseRouting();
  
              // global cors policy
              app.UseCors(x =&gt; x
                  .AllowAnyOrigin()
                  .AllowAnyMethod()
                  .AllowAnyHeader());
  
  
              app.UseAuthentication();
              app.UseAuthorization();
              app.UseEndpoints(endpoints =&gt;
              {
                  endpoints.MapControllerRoute(
                      name: &quot;default&quot;,
                      pattern: &quot;{controller}/{action=Index}/{id?}&quot;);
              });
  
  
              app.UseSpa(spa =&gt;
              {
                  // To learn more about options for serving an Angular SPA from ASP.NET Core,
                  // see https://go.microsoft.com/fwlink/?linkid=864501
  
                  spa.Options.SourcePath = &quot;ClientApp&quot;;
  
                  if (env.IsDevelopment())
                  {
                      spa.UseAngularCliServer(npmScript: &quot;start&quot;);
                  }
              });
          }
      }
  </code></pre>
  <p>Here is what my employee looks like</p>
  <pre><code>[Table(&quot;erp_empleados&quot;)]
  public class Employee : IdentityUser&lt;ulong&gt;
  {
      [Display(Name = &quot;empName&quot;, ResourceType = typeof(SharedResource))]
      [Column(&quot;nombre&quot;)]
      public string Name { get; set; }
  
      [Display(Name = &quot;empLastName&quot;, ResourceType = typeof(SharedResource))]
      [Column(&quot;apellido&quot;)]
      public string FamilyName { get; set; }
  
      [Display(Name = &quot;empEmail&quot;, ResourceType = typeof(SharedResource))]
      [Column(&quot;correo&quot;)]
      public override string Email { get; set; }
  
     //And many more fields
  
  }
  </code></pre>
  <p>Here is what my user role class looks like</p>
  <pre><code>[Table(&quot;erp_tipo_usuario&quot;)]
  public class Type : IdentityRole&lt;ulong&gt;
  {
  
  }
  </code></pre>
  <p>In my angular app I have the following code to guard my endpoints. I am not sure how to modify it so it requires claims? <strong>Update</strong> I now Understand I do not have to change anything in the jwt token the claims/roles will be included which is how it will work.</p>
  <pre><code>import { Injectable } from '@angular/core';
  import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
  
  @Injectable({
    providedIn: 'root'
  })
  export class AuthGuard implements CanActivate {
  
    constructor(private router: Router) { }
  
    canActivate(
      next: ActivatedRouteSnapshot,
      state: RouterStateSnapshot): boolean {
      if (localStorage.getItem('token') != null)
        return true;
      else {
        this.router.navigate(['/user/login']);
        return false;
      }
    }
  }
  </code></pre>
  <p>Too login In my app I have the following code.</p>
  <pre><code>[HttpPost, Route(&quot;login&quot;)]
  public async Task&lt;IActionResult&gt; Login([FromBody] LoginModel user)
  {
      string passowrdHashed = HashPassword(user.Password);
  
      var userFromDb = await _userManager.FindByNameAsync(user.UserName);
      if (userFromDb == null) 
      {
          return Unauthorized();
      }
      else if (user != null &amp;&amp; userFromDb.UserName==user.UserName
          &amp;&amp; userFromDb.PasswordHash == passowrdHashed)
      {
          if (userFromDb.PasswordHash == HashPassword(_employeeService.DEFAULT_PASSWORD))
          {                    
              return Ok(&quot;Please change password!&quot;); 
          }
          else
          {
             //*********************************************************************  
             //******      How to add Code to add ASP.NET Identity claims???????????????      *******
             //*********************************************************************
              var tokenDescriptor = new SecurityTokenDescriptor
              {
                  Subject = new ClaimsIdentity(new Claim[] {
                  new Claim(&quot;UserID&quot;, &quot;1&quot;)
                  new Claim(ClaimTypes.Role, role.NormalizedName),
              }),
                  Issuer = &quot;jcortenbach&quot;,
                  Expires = DateTime.UtcNow.AddHours(1),
                  SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(&quot;superlongKeyWithALotOfWordsToMakeItMoreSecureWhichIsGoodThankYouForReadingMySecretKey@45&quot;)), SecurityAlgorithms.HmacSha256Signature)
              };
              var tokenHandler = new JwtSecurityTokenHandler();
              var securityToken = tokenHandler.CreateToken(tokenDescriptor);
              var token = tokenHandler.WriteToken(securityToken);
              return Ok(new { token });
          }
      }
      else 
      {
          return Unauthorized();
      }
  }
  </code></pre>
  <p>Finally when it comes to my backend I think it should look something like this. For example the get client list code.</p>
  <pre><code>[Route(&quot;api/[controller]&quot;)]
  [ApiController]
  public class ClientsController : ControllerBase
  {
      private readonly ILogger&lt;ClientsController&gt; _logger;
      private readonly IClientService _clientService;
  
      public ClientsController(erp_colombiaDbContext context, ILogger&lt;ClientsController&gt; logger, IClientService clientService)
      {
          _logger = logger;
          _clientService = clientService;
      }
  
  // GET api/clients
  // **Update** I have add [Authorize(Roles = &quot;comercial&quot;)] and comment out the     [Authorize(Policy = &quot;ViewClientsPolicy&quot;)] and the authentication works for user role based authentication I however would like to have policy based authentication as well.
  [HttpGet]
  [Authorize(Roles = &quot;comercial&quot;)]
  [Authorize(Policy = &quot;ViewClientsPolicy&quot;)]
  public async Task&lt;IEnumerable&lt;ClientViewModel&gt;&gt; GetAsync()
  {
      ClientViewModel clientViewModel;
      List&lt;ClientViewModel&gt; listClientViewModels = new List&lt;ClientViewModel&gt;();
  
      var clients = await _clientService.GetAllClients();
  
      foreach (var client in clients) 
      {
          clientViewModel = new ClientViewModel();
          clientViewModel.ClientId = client.ClientId;
          clientViewModel.Active = client.Active;
          clientViewModel.Address = client.Address;
          clientViewModel.City = client.City;
          clientViewModel.ClienteName = client.ClienteName;
          clientViewModel.ComercialEmployeeId = client.ComercialEmployeeId;
          clientViewModel.Confirmed = client.Confirmed;
          clientViewModel.CountryId = client.CountryId;
          clientViewModel.CreationDate = client.CreationDate;
          clientViewModel.DANE = client.DANE;
          clientViewModel.Department = client.Department;
          clientViewModel.ElectronicBillingEmail = client.ElectronicBillingEmail;
          clientViewModel.Eliminated = client.Eliminated;
          clientViewModel.NIT = client.NIT;
          clientViewModel.PostalCode = client.PostalCode;
          clientViewModel.Phone = client.Phone;
  
          listClientViewModels.Add(clientViewModel);
      }
  
      return listClientViewModels;
  }
  </code></pre>
  <p>I am uncertain what to do next has there are many puzzle pieces. Your help is greatly appreciated.</p>
  <h2>Recap of Questions</h2>
  <ol>
  <li>How to add asp.net core roles to claims/policies?</li>
  <li>How to connect claims/policies to user?  <strong>DONE</strong></li>
  <li>What to add in startup for claims/policies to work?</li>
  <li>How to add claims/policies to jwt cookies?</li>
  <li>How to uses jwt claims/polices cookies in angular? <strong>DONE</strong> Will happen automatically when add it jwt cookie in login controller function</li>
  </ol>