{"id":1817,"date":"2023-06-14T12:48:13","date_gmt":"2023-06-14T12:48:13","guid":{"rendered":"http:\/\/waqar-arshad.com\/?p=1817"},"modified":"2023-06-14T12:48:13","modified_gmt":"2023-06-14T12:48:13","slug":"asp-net-core-authentication-and-authrization","status":"publish","type":"post","link":"http:\/\/waqar-arshad.com\/index.php\/2023\/06\/14\/asp-net-core-authentication-and-authrization\/","title":{"rendered":"Asp.Net Core Authentication and Authrization"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"1817\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><div class=\"pld-dislike-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-dislike-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"1817\" data-trigger-type=\"dislike\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-down\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-dislike-count-wrap pld-count-wrap\"><\/span>\r\n<\/div><\/div>\n<p><strong>Authentication And Authorization In ASP.NET Core Web API With JSON Web Tokens<\/strong><\/p>\n\n\n\n<p><strong>Introduction<\/strong><\/p>\n\n\n\n<p>Authentication is the process of validating user credentials and authorization is the process of checking privileges for a user to access specific modules in an application. In this article, we will see how to protect an ASP.NET Core Web API application by implementing JWT authentication. We will also see how to use authorization in ASP.NET Core to provide access to various functionality of the application. We will store user credentials in an SQL server database and we will use Entity framework and Identity framework for database operations.<\/p>\n\n\n\n<p>JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the&nbsp;<strong>HMAC&nbsp;<\/strong>algorithm) or a public\/private key pair using&nbsp;<strong>RSA&nbsp;<\/strong>or&nbsp;<strong>ECDSA<\/strong>.<\/p>\n\n\n\n<p>In its compact form, JSON Web Tokens consist of three parts separated by dots (.), which are:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Header<\/li>\n\n\n\n<li>Payload<\/li>\n\n\n\n<li>Signature<\/li>\n<\/ul>\n\n\n\n<p>Therefore, a JWT typically looks like the following.<\/p>\n\n\n\n<p><strong>xxxx.yyyy.zzzz<\/strong><\/p>\n\n\n\n<p>Please refer to below link for more details about JSON Web Tokens.<\/p>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/jwt.io\/introduction\/\n<\/div><\/figure>\n\n\n\n<p>Create ASP.NET Core Web API using Visual Studio 2019<\/p>\n\n\n\n<p>We can create an API application with ASP.NET Core Web API template.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"610\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-17.png\" alt=\"\" class=\"wp-image-1839\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-17.png 940w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-17-300x195.png 300w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-17-768x498.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>We must install below libraries using NuGet package manager.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Microsoft.EntityFrameworkCore.SqlServer<\/strong><\/li>\n\n\n\n<li><strong>Microsoft.EntityFrameworkCore.Tools<\/strong><\/li>\n\n\n\n<li><strong>Microsoft.AspNetCore.Identity.EntityFrameworkCore<\/strong><\/li>\n\n\n\n<li><strong>Microsoft.AspNetCore.Identity<\/strong><\/li>\n\n\n\n<li><strong>Microsoft.AspNetCore.Authentication.JwtBearer<\/strong><\/li>\n<\/ul>\n\n\n\n<p>We can modify the appsettings.json with below values.<\/p>\n\n\n\n<p><strong>appsettings.json<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li>{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&#8220;Logging&#8221;:&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;LogLevel&#8221;:&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Default&#8221;:&nbsp;&#8220;Information&#8221;,&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Microsoft&#8221;:&nbsp;&#8220;Warning&#8221;,&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Microsoft.Hosting.Lifetime&#8221;:&nbsp;&#8220;Information&#8221;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;},&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&#8220;AllowedHosts&#8221;:&nbsp;&#8220;*&#8221;,&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&#8220;ConnectionStrings&#8221;:&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;ConnStr&#8221;:&nbsp;&#8220;Data&nbsp;Source=(localdb)\\\\MSSQLLocalDB;Initial&nbsp;Catalog=SarathlalDB;Integrated&nbsp;Security=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False&#8221;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;},&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&#8220;JWT&#8221;:&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;ValidAudience&#8221;:&nbsp;&#8220;http:\/\/localhost:4200&#8221;,&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;ValidIssuer&#8221;:&nbsp;&#8220;http:\/\/localhost:61955&#8221;,&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&#8220;Secret&#8221;:&nbsp;&#8220;ByYM000OLlMQG6VVVp1OH7Xzyr7gHuw1qvUC5dcGt3SNM&#8221;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>}&nbsp;&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>We have added a database connection string and also added valid audience, valid issuer and secret key for JWT authentication in above settings file.<\/p>\n\n\n\n<p>Create an \u201cApplicationUser\u201d class inside a new folder \u201cAuthentication\u201d which will inherit the IdentityUser class. IdentityUser class is a part of Microsoft Identity framework. We will create all the authentication related files inside the \u201cAuthentication\u201d folder.<\/p>\n\n\n\n<p><strong>ApplicationUser.cs<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li><strong>using<\/strong>&nbsp;Microsoft.AspNetCore.Identity;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>namespace<\/strong>&nbsp;JWTAuthentication.Authentication&nbsp;&nbsp;<\/li>\n\n\n\n<li>{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>class<\/strong>&nbsp;ApplicationUser:&nbsp;IdentityUser&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>}&nbsp;&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>We can create the \u201cApplicationDbContext\u201d class and add below code.<\/p>\n\n\n\n<p><strong>ApplicationDbContext.cs<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li><strong>using<\/strong>&nbsp;Microsoft.AspNetCore.Identity.EntityFrameworkCore;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.EntityFrameworkCore;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>namespace<\/strong>&nbsp;JWTAuthentication.Authentication&nbsp;&nbsp;<\/li>\n\n\n\n<li>{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>class<\/strong>&nbsp;ApplicationDbContext&nbsp;:&nbsp;IdentityDbContext&lt;ApplicationUser&gt;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;ApplicationDbContext(DbContextOptions&lt;ApplicationDbContext&gt;&nbsp;options)&nbsp;:&nbsp;<strong>base<\/strong>(options)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>protected<\/strong>&nbsp;<strong>override<\/strong>&nbsp;<strong>void<\/strong>&nbsp;OnModelCreating(ModelBuilder&nbsp;builder)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>base<\/strong>.OnModelCreating(builder);&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>}&nbsp;&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>Create a static class \u201cUserRoles\u201d and add below values.<\/p>\n\n\n\n<p><strong>UserRoles.cs<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li><strong>namespace<\/strong>&nbsp;JWTAuthentication.Authentication&nbsp;&nbsp;<\/li>\n\n\n\n<li>{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>static<\/strong>&nbsp;<strong>class<\/strong>&nbsp;UserRoles&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>const<\/strong>&nbsp;<strong>string<\/strong>&nbsp;Admin&nbsp;=&nbsp;&#8220;Admin&#8221;;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>const<\/strong>&nbsp;<strong>string<\/strong>&nbsp;User&nbsp;=&nbsp;&#8220;User&#8221;;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>}&nbsp;&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>We have added two constant values \u201cAdmin\u201d and \u201cUser\u201d as roles. You can add many roles as you wish.<\/p>\n\n\n\n<p>Create class \u201cRegisterModel\u201d for new user registration.<\/p>\n\n\n\n<p><strong>RegisterModel.cs<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li><strong>using<\/strong>&nbsp;System.ComponentModel.DataAnnotations;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>namespace<\/strong>&nbsp;JWTAuthentication.Authentication&nbsp;&nbsp;<\/li>\n\n\n\n<li>{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>class<\/strong>&nbsp;RegisterModel&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Required(ErrorMessage&nbsp;=&nbsp;&#8220;User&nbsp;Name&nbsp;is&nbsp;required&#8221;)]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>string<\/strong>&nbsp;Username&nbsp;{&nbsp;<strong>get<\/strong>;&nbsp;<strong>set<\/strong>;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[EmailAddress]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Required(ErrorMessage&nbsp;=&nbsp;&#8220;Email&nbsp;is&nbsp;required&#8221;)]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>string<\/strong>&nbsp;Email&nbsp;{&nbsp;<strong>get<\/strong>;&nbsp;<strong>set<\/strong>;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Required(ErrorMessage&nbsp;=&nbsp;&#8220;Password&nbsp;is&nbsp;required&#8221;)]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>string<\/strong>&nbsp;Password&nbsp;{&nbsp;<strong>get<\/strong>;&nbsp;<strong>set<\/strong>;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>}&nbsp;&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>Create class \u201cLoginModel\u201d for user login.<\/p>\n\n\n\n<p><strong>LoginModel.cs<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li><strong>using<\/strong>&nbsp;System.ComponentModel.DataAnnotations;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>namespace<\/strong>&nbsp;JWTAuthentication.Authentication&nbsp;&nbsp;<\/li>\n\n\n\n<li>{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>class<\/strong>&nbsp;LoginModel&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Required(ErrorMessage&nbsp;=&nbsp;&#8220;User&nbsp;Name&nbsp;is&nbsp;required&#8221;)]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>string<\/strong>&nbsp;Username&nbsp;{&nbsp;<strong>get<\/strong>;&nbsp;<strong>set<\/strong>;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Required(ErrorMessage&nbsp;=&nbsp;&#8220;Password&nbsp;is&nbsp;required&#8221;)]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>string<\/strong>&nbsp;Password&nbsp;{&nbsp;<strong>get<\/strong>;&nbsp;<strong>set<\/strong>;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>}&nbsp;&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>We can create a class \u201cResponse\u201d for returning the response value after user registration and user login. It will also return error messages, if the request fails.<\/p>\n\n\n\n<p><strong>Response.cs<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li><strong>namespace<\/strong>&nbsp;JWTAuthentication.Authentication&nbsp;&nbsp;<\/li>\n\n\n\n<li>{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>class<\/strong>&nbsp;Response&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>string<\/strong>&nbsp;Status&nbsp;{&nbsp;<strong>get<\/strong>;&nbsp;<strong>set<\/strong>;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>string<\/strong>&nbsp;Message&nbsp;{&nbsp;<strong>get<\/strong>;&nbsp;<strong>set<\/strong>;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>}&nbsp;&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>We can create an API controller \u201cAuthenticateController\u201d inside the \u201cControllers\u201d folder and add below code.<\/p>\n\n\n\n<p><strong>AuthenticateController.cs<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li><strong>using<\/strong>&nbsp;JWTAuthentication.Authentication;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.AspNetCore.Http;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.AspNetCore.Identity;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.AspNetCore.Mvc;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.Extensions.Configuration;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.IdentityModel.Tokens;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;System;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;System.Collections.Generic;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;System.IdentityModel.Tokens.Jwt;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;System.Security.Claims;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;System.Text;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;System.Threading.Tasks;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>namespace<\/strong>&nbsp;JWTAuthentication.Controllers&nbsp;&nbsp;<\/li>\n\n\n\n<li>{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;[Route(&#8220;api\/[controller]&#8221;)]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;[ApiController]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>class<\/strong>&nbsp;AuthenticateController&nbsp;:&nbsp;ControllerBase&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>private<\/strong>&nbsp;<strong>readonly<\/strong>&nbsp;UserManager&lt;ApplicationUser&gt;&nbsp;userManager;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>private<\/strong>&nbsp;<strong>readonly<\/strong>&nbsp;RoleManager&lt;IdentityRole&gt;&nbsp;roleManager;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>private<\/strong>&nbsp;<strong>readonly<\/strong>&nbsp;IConfiguration&nbsp;_configuration;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;AuthenticateController(UserManager&lt;ApplicationUser&gt;&nbsp;userManager,&nbsp;RoleManager&lt;IdentityRole&gt;&nbsp;roleManager,&nbsp;IConfiguration&nbsp;configuration)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>this<\/strong>.userManager&nbsp;=&nbsp;userManager;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>this<\/strong>.roleManager&nbsp;=&nbsp;roleManager;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_configuration&nbsp;=&nbsp;configuration;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[HttpPost]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Route(&#8220;login&#8221;)]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;async&nbsp;Task&lt;IActionResult&gt;&nbsp;Login([FromBody]&nbsp;LoginModel&nbsp;model)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;user&nbsp;=&nbsp;await&nbsp;userManager.FindByNameAsync(model.Username);&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>if<\/strong>&nbsp;(user&nbsp;!=&nbsp;<strong>null<\/strong>&nbsp;&amp;&amp;&nbsp;await&nbsp;userManager.CheckPasswordAsync(user,&nbsp;model.Password))&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;userRoles&nbsp;=&nbsp;await&nbsp;userManager.GetRolesAsync(user);&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;authClaims&nbsp;=&nbsp;<strong>new<\/strong>&nbsp;List&lt;Claim&gt;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>new<\/strong>&nbsp;Claim(ClaimTypes.Name,&nbsp;user.UserName),&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>new<\/strong>&nbsp;Claim(JwtRegisteredClaimNames.Jti,&nbsp;Guid.NewGuid().ToString()),&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>foreach<\/strong>&nbsp;(var&nbsp;userRole&nbsp;<strong>in<\/strong>&nbsp;userRoles)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;authClaims.Add(<strong>new<\/strong>&nbsp;Claim(ClaimTypes.Role,&nbsp;userRole));&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;authSigningKey&nbsp;=&nbsp;<strong>new<\/strong>&nbsp;SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration[&#8220;JWT:Secret&#8221;]));&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;token&nbsp;=&nbsp;<strong>new<\/strong>&nbsp;JwtSecurityToken(&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;issuer:&nbsp;_configuration[&#8220;JWT:ValidIssuer&#8221;],&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;audience:&nbsp;_configuration[&#8220;JWT:ValidAudience&#8221;],&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expires:&nbsp;DateTime.Now.AddHours(3),&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;claims:&nbsp;authClaims,&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;signingCredentials:&nbsp;<strong>new<\/strong>&nbsp;SigningCredentials(authSigningKey,&nbsp;SecurityAlgorithms.HmacSha256)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>return<\/strong>&nbsp;Ok(<strong>new<\/strong>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;token&nbsp;=&nbsp;<strong>new<\/strong>&nbsp;JwtSecurityTokenHandler().WriteToken(token),&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expiration&nbsp;=&nbsp;token.ValidTo&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>return<\/strong>&nbsp;Unauthorized();&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[HttpPost]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Route(&#8220;register&#8221;)]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;async&nbsp;Task&lt;IActionResult&gt;&nbsp;Register([FromBody]&nbsp;RegisterModel&nbsp;model)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;userExists&nbsp;=&nbsp;await&nbsp;userManager.FindByNameAsync(model.Username);&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>if<\/strong>&nbsp;(userExists&nbsp;!=&nbsp;<strong>null<\/strong>)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>return<\/strong>&nbsp;StatusCode(StatusCodes.Status500InternalServerError,&nbsp;<strong>new<\/strong>&nbsp;Response&nbsp;{&nbsp;Status&nbsp;=&nbsp;&#8220;Error&#8221;,&nbsp;Message&nbsp;=&nbsp;&#8220;User&nbsp;already&nbsp;exists!&#8221;&nbsp;});&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApplicationUser&nbsp;user&nbsp;=&nbsp;<strong>new<\/strong>&nbsp;ApplicationUser()&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;=&nbsp;model.Email,&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SecurityStamp&nbsp;=&nbsp;Guid.NewGuid().ToString(),&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserName&nbsp;=&nbsp;model.Username&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;result&nbsp;=&nbsp;await&nbsp;userManager.CreateAsync(user,&nbsp;model.Password);&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>if<\/strong>&nbsp;(!result.Succeeded)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>return<\/strong>&nbsp;StatusCode(StatusCodes.Status500InternalServerError,&nbsp;<strong>new<\/strong>&nbsp;Response&nbsp;{&nbsp;Status&nbsp;=&nbsp;&#8220;Error&#8221;,&nbsp;Message&nbsp;=&nbsp;&#8220;User&nbsp;creation&nbsp;failed!&nbsp;Please&nbsp;check&nbsp;user&nbsp;details&nbsp;and&nbsp;try&nbsp;again.&#8221;&nbsp;});&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>return<\/strong>&nbsp;Ok(<strong>new<\/strong>&nbsp;Response&nbsp;{&nbsp;Status&nbsp;=&nbsp;&#8220;Success&#8221;,&nbsp;Message&nbsp;=&nbsp;&#8220;User&nbsp;created&nbsp;successfully!&#8221;&nbsp;});&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[HttpPost]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Route(&#8220;register-admin&#8221;)]&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;async&nbsp;Task&lt;IActionResult&gt;&nbsp;RegisterAdmin([FromBody]&nbsp;RegisterModel&nbsp;model)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;userExists&nbsp;=&nbsp;await&nbsp;userManager.FindByNameAsync(model.Username);&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>if<\/strong>&nbsp;(userExists&nbsp;!=&nbsp;<strong>null<\/strong>)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>return<\/strong>&nbsp;StatusCode(StatusCodes.Status500InternalServerError,&nbsp;<strong>new<\/strong>&nbsp;Response&nbsp;{&nbsp;Status&nbsp;=&nbsp;&#8220;Error&#8221;,&nbsp;Message&nbsp;=&nbsp;&#8220;User&nbsp;already&nbsp;exists!&#8221;&nbsp;});&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApplicationUser&nbsp;user&nbsp;=&nbsp;<strong>new<\/strong>&nbsp;ApplicationUser()&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Email&nbsp;=&nbsp;model.Email,&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SecurityStamp&nbsp;=&nbsp;Guid.NewGuid().ToString(),&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserName&nbsp;=&nbsp;model.Username&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;result&nbsp;=&nbsp;await&nbsp;userManager.CreateAsync(user,&nbsp;model.Password);&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>if<\/strong>&nbsp;(!result.Succeeded)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>return<\/strong>&nbsp;StatusCode(StatusCodes.Status500InternalServerError,&nbsp;<strong>new<\/strong>&nbsp;Response&nbsp;{&nbsp;Status&nbsp;=&nbsp;&#8220;Error&#8221;,&nbsp;Message&nbsp;=&nbsp;&#8220;User&nbsp;creation&nbsp;failed!&nbsp;Please&nbsp;check&nbsp;user&nbsp;details&nbsp;and&nbsp;try&nbsp;again.&#8221;&nbsp;});&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>if<\/strong>&nbsp;(!await&nbsp;roleManager.RoleExistsAsync(UserRoles.Admin))&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;await&nbsp;roleManager.CreateAsync(<strong>new<\/strong>&nbsp;IdentityRole(UserRoles.Admin));&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>if<\/strong>&nbsp;(!await&nbsp;roleManager.RoleExistsAsync(UserRoles.User))&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;await&nbsp;roleManager.CreateAsync(<strong>new<\/strong>&nbsp;IdentityRole(UserRoles.User));&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>if<\/strong>&nbsp;(await&nbsp;roleManager.RoleExistsAsync(UserRoles.Admin))&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;await&nbsp;userManager.AddToRoleAsync(user,&nbsp;UserRoles.Admin);&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>return<\/strong>&nbsp;Ok(<strong>new<\/strong>&nbsp;Response&nbsp;{&nbsp;Status&nbsp;=&nbsp;&#8220;Success&#8221;,&nbsp;Message&nbsp;=&nbsp;&#8220;User&nbsp;created&nbsp;successfully!&#8221;&nbsp;});&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>}&nbsp;&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>We have added three methods \u201clogin\u201d, \u201cregister\u201d, and \u201cregister-admin\u201d inside the controller class. Register and register-admin are almost same but the register-admin method will be used to create a user with admin role. In login method, we have returned a JWT token after successful login.<\/p>\n\n\n\n<p>We can make below changes in \u201cConfigureServices\u201d and \u201cConfigure\u201d methods in \u201cStartup\u201d class as well.<\/p>\n\n\n\n<p><strong>Startup.cs<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\">\n<li><strong>using<\/strong>&nbsp;JWTAuthentication.Authentication;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.AspNetCore.Authentication.JwtBearer;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.AspNetCore.Builder;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.AspNetCore.Hosting;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.AspNetCore.Identity;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.EntityFrameworkCore;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.Extensions.Configuration;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.Extensions.DependencyInjection;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.Extensions.Hosting;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;Microsoft.IdentityModel.Tokens;&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>using<\/strong>&nbsp;System.Text;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li><strong>namespace<\/strong>&nbsp;JWTAuthentication&nbsp;&nbsp;<\/li>\n\n\n\n<li>{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>class<\/strong>&nbsp;Startup&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;Startup(IConfiguration&nbsp;configuration)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Configuration&nbsp;=&nbsp;configuration;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;IConfiguration&nbsp;Configuration&nbsp;{&nbsp;<strong>get<\/strong>;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/&nbsp;This&nbsp;method&nbsp;gets&nbsp;called&nbsp;by&nbsp;the&nbsp;runtime.&nbsp;Use&nbsp;this&nbsp;method&nbsp;to&nbsp;add&nbsp;services&nbsp;to&nbsp;the&nbsp;container.&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>void<\/strong>&nbsp;ConfigureServices(IServiceCollection&nbsp;services)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;services.AddControllers();&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/&nbsp;For&nbsp;Entity&nbsp;Framework&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;services.AddDbContext&lt;ApplicationDbContext&gt;(options&nbsp;=&gt;&nbsp;options.UseSqlServer(Configuration.GetConnectionString(&#8220;ConnStr&#8221;)));&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/&nbsp;For&nbsp;Identity&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;services.AddIdentity&lt;ApplicationUser,&nbsp;IdentityRole&gt;()&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.AddEntityFrameworkStores&lt;ApplicationDbContext&gt;()&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.AddDefaultTokenProviders();&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/&nbsp;Adding&nbsp;Authentication&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;services.AddAuthentication(options&nbsp;=&gt;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options.DefaultAuthenticateScheme&nbsp;=&nbsp;JwtBearerDefaults.AuthenticationScheme;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options.DefaultChallengeScheme&nbsp;=&nbsp;JwtBearerDefaults.AuthenticationScheme;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options.DefaultScheme&nbsp;=&nbsp;JwtBearerDefaults.AuthenticationScheme;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;})&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/&nbsp;Adding&nbsp;Jwt&nbsp;Bearer&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.AddJwtBearer(options&nbsp;=&gt;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options.SaveToken&nbsp;=&nbsp;<strong>true<\/strong>;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options.RequireHttpsMetadata&nbsp;=&nbsp;<strong>false<\/strong>;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;options.TokenValidationParameters&nbsp;=&nbsp;<strong>new<\/strong>&nbsp;TokenValidationParameters()&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValidateIssuer&nbsp;=&nbsp;<strong>true<\/strong>,&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValidateAudience&nbsp;=&nbsp;<strong>true<\/strong>,&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValidAudience&nbsp;=&nbsp;Configuration[&#8220;JWT:ValidAudience&#8221;],&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ValidIssuer&nbsp;=&nbsp;Configuration[&#8220;JWT:ValidIssuer&#8221;],&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IssuerSigningKey&nbsp;=&nbsp;<strong>new<\/strong>&nbsp;SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration[&#8220;JWT:Secret&#8221;]))&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\/\/&nbsp;This&nbsp;method&nbsp;gets&nbsp;called&nbsp;by&nbsp;the&nbsp;runtime.&nbsp;Use&nbsp;this&nbsp;method&nbsp;to&nbsp;configure&nbsp;the&nbsp;HTTP&nbsp;request&nbsp;pipeline.&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>public<\/strong>&nbsp;<strong>void<\/strong>&nbsp;Configure(IApplicationBuilder&nbsp;app,&nbsp;IWebHostEnvironment&nbsp;env)&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<strong>if<\/strong>&nbsp;(env.IsDevelopment())&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;app.UseDeveloperExceptionPage();&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;app.UseRouting();&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;app.UseAuthentication();&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;app.UseAuthorization();&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;app.UseEndpoints(endpoints&nbsp;=&gt;&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;endpoints.MapControllers();&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<\/li>\n\n\n\n<li>}&nbsp;&nbsp;<\/li>\n<\/ol>\n\n\n\n<p>We can add \u201cAuthorize\u201d attribute inside the \u201cWeatherForecast\u201d controller.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"818\" height=\"453\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-18.png\" alt=\"\" class=\"wp-image-1840\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-18.png 818w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-18-300x166.png 300w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-18-768x425.png 768w\" sizes=\"auto, (max-width: 818px) 100vw, 818px\" \/><\/figure>\n\n\n\n<p>We must create a database and required tables before running the application. As we are using entity framework, we can use below database migration command with package manger console to create a migration script.<\/p>\n\n\n\n<p><strong><em>\u201cadd-migration Initial\u201d<\/em><\/strong><\/p>\n\n\n\n<p>Use below command to create database and tables.<\/p>\n\n\n\n<p><strong><em>\u201cupdate-database\u201d<\/em><\/strong><\/p>\n\n\n\n<p>If you check the database using SQL server object explorer, you can see that below tables are created inside the database.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"486\" height=\"433\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-19.png\" alt=\"\" class=\"wp-image-1841\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-19.png 486w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-19-300x267.png 300w\" sizes=\"auto, (max-width: 486px) 100vw, 486px\" \/><\/figure>\n\n\n\n<p>Above seven tables are used by identity framework to manage authentication and authorization.<\/p>\n\n\n\n<p>We can run the application and try to access get method in weatherforecast controller from Postman tool.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"751\" height=\"480\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-20.png\" alt=\"\" class=\"wp-image-1842\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-20.png 751w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-20-300x192.png 300w\" sizes=\"auto, (max-width: 751px) 100vw, 751px\" \/><\/figure>\n\n\n\n<p>We have received a 401 unauthorized error. Because, we have added Authorize attribute to entire controller. We must provide a valid token via request header to access this controller and methods inside the controller.<\/p>\n\n\n\n<p>We can create a new user using register method in authenticate controller.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"681\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-21.png\" alt=\"\" class=\"wp-image-1843\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-21.png 940w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-21-300x217.png 300w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-21-768x556.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>We can use above user credentials to login and get a valid JWT token.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"472\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-22.png\" alt=\"\" class=\"wp-image-1844\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-22.png 940w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-22-300x151.png 300w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-22-768x386.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>We have received a token after successful login with above credentials.<\/p>\n\n\n\n<p>We can pass above token value as a bearer token inside the authorization tab and call get method of weatherforecast controller again.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"560\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-23.png\" alt=\"\" class=\"wp-image-1845\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-23.png 940w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-23-300x179.png 300w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-23-768x458.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>This time, we have successfully received the values from controller.<\/p>\n\n\n\n<p>We can modify the weatherforecast controller with role-based authorization.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"807\" height=\"428\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-24.png\" alt=\"\" class=\"wp-image-1846\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-24.png 807w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-24-300x159.png 300w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-24-768x407.png 768w\" sizes=\"auto, (max-width: 807px) 100vw, 807px\" \/><\/figure>\n\n\n\n<p>Now, only users with admin role can access this controller and methods.<\/p>\n\n\n\n<p>We can try to access the weatherforecast controller with same token again in Postman tool.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"730\" height=\"393\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-25.png\" alt=\"\" class=\"wp-image-1847\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-25.png 730w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-25-300x162.png 300w\" sizes=\"auto, (max-width: 730px) 100vw, 730px\" \/><\/figure>\n\n\n\n<p>We have received a 403 forbidden error now. Even though, we are passing a valid token we don\u2019t have sufficient privilege to access the controller. To access this controller, user must have an admin role permission. Current user is a normal user and do not have any admin role permission.<\/p>\n\n\n\n<p>We can create a new user with admin role. We already have a method \u201cregister-admin\u201d in authenticate controller for the same purpose.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"598\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-26.png\" alt=\"\" class=\"wp-image-1848\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-26.png 940w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-26-300x191.png 300w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-26-768x489.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>We can login with this new user credentials and get a new token and use this token instead of old token to access the weatherforecast controller.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"564\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-27.png\" alt=\"\" class=\"wp-image-1849\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-27.png 940w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-27-300x180.png 300w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-27-768x461.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>We have again received the values from weatherforecast controller successfully.<\/p>\n\n\n\n<p>We can see the token payload and other details using\u00a0<strong>jwt.io<\/strong>\u00a0site.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"940\" height=\"591\" src=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-28.png\" alt=\"\" class=\"wp-image-1850\" srcset=\"http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-28.png 940w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-28-300x189.png 300w, http:\/\/waqar-arshad.com\/wp-content\/uploads\/2023\/06\/image-28-768x483.png 768w\" sizes=\"auto, (max-width: 940px) 100vw, 940px\" \/><\/figure>\n\n\n\n<p>Inside the payload section, you can see the user name, role and other details as claims.<\/p>\n\n\n\n<p>Conclusion<\/p>\n\n\n\n<p>In this post, we have seen how to create a JSON web token in ASP.NET Core Web API application and use this token for authentication and authorization. We have created two users, one without any role and one with admin role. We have applied the authentication and authorization in controller level and saw the different behaviors with these two users.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Overview of ASP.NET Core authentication<\/h1>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Article<\/li>\n\n\n\n<li>06\/04\/2022<\/li>\n\n\n\n<li>11 minutes to read<\/li>\n\n\n\n<li>14 contributors<\/li>\n<\/ul>\n\n\n\n<p>By&nbsp;<a href=\"https:\/\/github.com\/mjrousos\">Mike Rousos<\/a><\/p>\n\n\n\n<p>Authentication is the process of determining a user&#8217;s identity.&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authorization\/introduction?view=aspnetcore-6.0\">Authorization<\/a>&nbsp;is the process of determining whether a user has access to a resource. In ASP.NET Core, authentication is handled by the authentication service,&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.authentication.iauthenticationservice\">IAuthenticationService<\/a>, which is used by authentication&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/fundamentals\/middleware\/?view=aspnetcore-6.0\">middleware<\/a>. The authentication service uses registered authentication handlers to complete authentication-related actions. Examples of authentication-related actions include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Authenticating a user.<\/li>\n\n\n\n<li>Responding when an unauthenticated user tries to access a restricted resource.<\/li>\n<\/ul>\n\n\n\n<p>The registered authentication handlers and their configuration options are called &#8220;schemes&#8221;.<\/p>\n\n\n\n<p>Authentication schemes are specified by registering authentication services in&nbsp;<code>Program.cs<\/code>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>By calling a scheme-specific extension method after a call to&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.extensions.dependencyinjection.authenticationservicecollectionextensions.addauthentication\">AddAuthentication<\/a>, such as&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.extensions.dependencyinjection.jwtbearerextensions.addjwtbearer\">AddJwtBearer<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.extensions.dependencyinjection.cookieextensions.addcookie\">AddCookie<\/a>. These extension methods use&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.authentication.authenticationbuilder.addscheme\">AuthenticationBuilder.AddScheme<\/a>&nbsp;to register schemes with appropriate settings.<\/li>\n\n\n\n<li>Less commonly, by calling&nbsp;<code>AuthenticationBuilder.AddScheme<\/code>&nbsp;directly.<\/li>\n<\/ul>\n\n\n\n<p>For example, the following code registers authentication services and handlers for cookie and JWT bearer authentication schemes:<\/p>\n\n\n\n<p>C#Copy<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>&nbsp;&nbsp;&nbsp; .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme,<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; options =&gt; builder.Configuration.Bind(<\/code>\"JwtSettings\"<code>, options))<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>&nbsp;&nbsp;&nbsp; .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; options =&gt; builder.Configuration.Bind(<\/code>\"CookieSettings\"<code>, options));<\/code><\/pre>\n\n\n\n<p>The&nbsp;<code>AddAuthentication<\/code>&nbsp;parameter&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.authentication.jwtbearer.jwtbearerdefaults.authenticationscheme\">JwtBearerDefaults.AuthenticationScheme<\/a>&nbsp;is the name of the scheme to use by default when a specific scheme isn&#8217;t requested.<\/p>\n\n\n\n<p>If multiple schemes are used, authorization policies (or authorization attributes) can&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authorization\/limitingidentitybyscheme?view=aspnetcore-6.0\">specify the authentication scheme (or schemes)<\/a>&nbsp;they depend on to authenticate the user. In the example above, the cookie authentication scheme could be used by specifying its name (<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.authentication.cookies.cookieauthenticationdefaults.authenticationscheme\">CookieAuthenticationDefaults.AuthenticationScheme<\/a>&nbsp;by default, though a different name could be provided when calling&nbsp;<code>AddCookie<\/code>).<\/p>\n\n\n\n<p>In some cases, the call to&nbsp;<code>AddAuthentication<\/code>&nbsp;is automatically made by other extension methods. For example, when using&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authentication\/identity?view=aspnetcore-6.0\">ASP.NET Core Identity<\/a>,&nbsp;<code>AddAuthentication<\/code>&nbsp;is called internally.<\/p>\n\n\n\n<p>The Authentication middleware is added in&nbsp;<code>Program.cs<\/code>&nbsp;by calling&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.builder.authappbuilderextensions.useauthentication\">UseAuthentication<\/a>. Calling&nbsp;<code>UseAuthentication<\/code>&nbsp;registers the middleware that uses the previously registered authentication schemes. Call&nbsp;<code>UseAuthentication<\/code>&nbsp;before any middleware that depends on users being authenticated.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Authentication concepts<\/h2>\n\n\n\n<p>Authentication is responsible for providing the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.security.claims.claimsprincipal\">ClaimsPrincipal<\/a>&nbsp;for authorization to make permission decisions against. There are multiple authentication scheme approaches to select which authentication handler is responsible for generating the correct set of claims:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authentication\/?view=aspnetcore-6.0#authentication-scheme\">Authentication scheme<\/a><\/li>\n\n\n\n<li>The default authentication scheme, discussed in the next section.<\/li>\n\n\n\n<li>Directly set&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.http.httpcontext.user#microsoft-aspnetcore-http-httpcontext-user\">HttpContext.User<\/a>.<\/li>\n<\/ul>\n\n\n\n<p>There&#8217;s no automatic probing of schemes. If the default scheme isn&#8217;t specified, the scheme must be specified in the authorize attribute, otherwise, the following error is thrown:<\/p>\n\n\n\n<p>InvalidOperationException: No authenticationScheme was specified, and there was no DefaultAuthenticateScheme found. The default schemes can be set using either AddAuthentication(string defaultScheme) or AddAuthentication(Action&lt;AuthenticationOptions&gt; configureOptions).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Authentication scheme<\/h3>\n\n\n\n<p>The&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authorization\/limitingidentitybyscheme?view=aspnetcore-6.0\">authentication scheme<\/a>&nbsp;can select which authentication handler is responsible for generating the correct set of claims. For more information, see&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authorization\/limitingidentitybyscheme?view=aspnetcore-6.0\">Authorize with a specific scheme<\/a>.<\/p>\n\n\n\n<p>An authentication scheme is a name that corresponds to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An authentication handler.<\/li>\n\n\n\n<li>Options for configuring that specific instance of the handler.<\/li>\n<\/ul>\n\n\n\n<p>Schemes are useful as a mechanism for referring to the authentication, challenge, and forbid behaviors of the associated handler. For example, an authorization policy can use scheme names to specify which authentication scheme (or schemes) should be used to authenticate the user. When configuring authentication, it&#8217;s common to specify the default authentication scheme. The default scheme is used unless a resource requests a specific scheme. It&#8217;s also possible to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Specify different default schemes to use for authenticate, challenge, and forbid actions.<\/li>\n\n\n\n<li>Combine multiple schemes into one using&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authentication\/policyschemes?view=aspnetcore-6.0\">policy schemes<\/a>.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Authentication handler<\/h3>\n\n\n\n<p>An authentication handler:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Is a type that implements the behavior of a scheme.<\/li>\n\n\n\n<li>Is derived from&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.authentication.iauthenticationhandler\">IAuthenticationHandler<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.authentication.authenticationhandler-1\">AuthenticationHandler&lt;TOptions&gt;<\/a>.<\/li>\n\n\n\n<li>Has the primary responsibility to authenticate users.<\/li>\n<\/ul>\n\n\n\n<p>Based on the authentication scheme&#8217;s configuration and the incoming request context, authentication handlers:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Construct&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.authentication.authenticationticket\">AuthenticationTicket<\/a>&nbsp;objects representing the user&#8217;s identity if authentication is successful.<\/li>\n\n\n\n<li>Return &#8216;no result&#8217; or &#8216;failure&#8217; if authentication is unsuccessful.<\/li>\n\n\n\n<li>Have methods for challenge and forbid actions for when users attempt to access resources:<ul><li>They&#8217;re unauthorized to access (forbid).<\/li><\/ul>\n<ul class=\"wp-block-list\">\n<li>When they&#8217;re unauthenticated (challenge).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><code>RemoteAuthenticationHandler&lt;TOptions&gt;<\/code>&nbsp;vs&nbsp;<code>AuthenticationHandler&lt;TOptions&gt;<\/code><\/h3>\n\n\n\n<p><a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.authentication.remoteauthenticationhandler-1\">RemoteAuthenticationHandler&lt;TOptions&gt;<\/a>&nbsp;is the class for authentication that requires a remote authentication step. When the remote authentication step is finished, the handler calls back to the&nbsp;<code>CallbackPath<\/code>&nbsp;set by the handler. The handler finishes the authentication step using the information passed to the&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.authentication.twitter.twitterhandler.handleremoteauthenticateasync\">HandleRemoteAuthenticateAsync<\/a>&nbsp;callback path.&nbsp;<a href=\"https:\/\/oauth.net\/2\/\">OAuth 2.0<\/a>&nbsp;and&nbsp;<a href=\"https:\/\/openid.net\/connect\/\">OIDC<\/a>&nbsp;both use this pattern. JWT and cookies don&#8217;t since they can directly use the bearer header and cookie to authenticate. The remotely hosted provider in this case:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Is the authentication provider.<\/li>\n\n\n\n<li>Examples include&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authentication\/social\/facebook-logins?view=aspnetcore-6.0\">Facebook<\/a>,&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authentication\/social\/twitter-logins?view=aspnetcore-6.0\">Twitter<\/a>,&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authentication\/social\/google-logins?view=aspnetcore-6.0\">Google<\/a>,&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authentication\/social\/microsoft-logins?view=aspnetcore-6.0\">Microsoft<\/a>, and any other OIDC provider that handles authenticating users using the handlers mechanism.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Authenticate<\/h3>\n\n\n\n<p>An authentication scheme&#8217;s authenticate action is responsible for constructing the user&#8217;s identity based on request context. It returns an&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.authentication.authenticateresult\">AuthenticateResult<\/a>&nbsp;indicating whether authentication was successful and, if so, the user&#8217;s identity in an authentication ticket. See&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.authentication.authenticationhttpcontextextensions.authenticateasync\">AuthenticateAsync<\/a>. Authenticate examples include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A cookie authentication scheme constructing the user&#8217;s identity from cookies.<\/li>\n\n\n\n<li>A JWT bearer scheme deserializing and validating a JWT bearer token to construct the user&#8217;s identity.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Challenge<\/h3>\n\n\n\n<p>An authentication challenge is invoked by Authorization when an unauthenticated user requests an endpoint that requires authentication. An authentication challenge is issued, for example, when an anonymous user requests a restricted resource or follows a login link. Authorization invokes a challenge using the specified authentication scheme(s), or the default if none is specified. See&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.authentication.authenticationhttpcontextextensions.challengeasync\">ChallengeAsync<\/a>. Authentication challenge examples include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A cookie authentication scheme redirecting the user to a login page.<\/li>\n\n\n\n<li>A JWT bearer scheme returning a 401 result with a&nbsp;<code>www-authenticate: bearer<\/code>&nbsp;header.<\/li>\n<\/ul>\n\n\n\n<p>A challenge action should let the user know what authentication mechanism to use to access the requested resource.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Forbid<\/h3>\n\n\n\n<p>An authentication scheme&#8217;s forbid action is called by Authorization when an authenticated user attempts to access a resource they&#8217;re not permitted to access. See&nbsp;<a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/microsoft.aspnetcore.authentication.authenticationhttpcontextextensions.forbidasync\">ForbidAsync<\/a>. Authentication forbid examples include:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A cookie authentication scheme redirecting the user to a page indicating access was forbidden.<\/li>\n\n\n\n<li>A JWT bearer scheme returning a 403 result.<\/li>\n\n\n\n<li>A custom authentication scheme redirecting to a page where the user can request access to the resource.<\/li>\n<\/ul>\n\n\n\n<p>A forbid action can let the user know:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>They&#8217;re authenticated.<\/li>\n\n\n\n<li>They&#8217;re not permitted to access the requested resource.<\/li>\n<\/ul>\n\n\n\n<p>See the following links for differences between challenge and forbid:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authorization\/resourcebased?view=aspnetcore-6.0#challenge-and-forbid-with-an-operational-resource-handler\">Challenge and forbid with an operational resource handler<\/a>.<\/li>\n\n\n\n<li><a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authorization\/secure-data?view=aspnetcore-6.0#challenge\">Differences between challenge and forbid<\/a>.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Authentication providers per tenant<\/h2>\n\n\n\n<p>ASP.NET Core doesn&#8217;t have a built-in solution for multi-tenant authentication. While it&#8217;s possible for customers to write one using the built-in features, we recommend customers to consider&nbsp;<a href=\"https:\/\/www.orchardcore.net\/\">Orchard Core<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/abp.io\/\">ABP Framework<\/a>&nbsp;for multi-tenant authentication.<\/p>\n\n\n\n<p>Orchard Core is:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>An open-source, modular, and multi-tenant app framework built with ASP.NET Core.<\/li>\n\n\n\n<li>A content management system (CMS) built on top of that app framework.<\/li>\n<\/ul>\n\n\n\n<p>See the&nbsp;<a href=\"https:\/\/github.com\/OrchardCMS\/OrchardCore\">Orchard Core<\/a>&nbsp;source for an example of authentication providers per tenant.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Authentication And Authorization In ASP.NET Core Web API With JSON Web Tokens Introduction Authentication is the process of validating user credentials and authorization is the process of checking privileges for a user to access specific modules in an application. In this article, we will see how to protect an ASP.NET Core Web API application by [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[13],"tags":[],"class_list":["post-1817","post","type-post","status-publish","format-standard","hentry","category-asp-net-core"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"admin","author_link":"http:\/\/waqar-arshad.com\/index.php\/author\/waqar_29_1\/"},"uagb_comment_info":32,"uagb_excerpt":"Authentication And Authorization In ASP.NET Core Web API With JSON Web Tokens Introduction Authentication is the process of validating user credentials and authorization is the process of checking privileges for a user to access specific modules in an application. In this article, we will see how to protect an ASP.NET Core Web API application by&hellip;","_links":{"self":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/1817","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/comments?post=1817"}],"version-history":[{"count":1,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/1817\/revisions"}],"predecessor-version":[{"id":1851,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/1817\/revisions\/1851"}],"wp:attachment":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/media?parent=1817"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/categories?post=1817"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/tags?post=1817"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}