In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
This article introduces the relevant knowledge of "how to add JWT authentication and authorization functions in ASP.NET Core 6.0. in the operation of actual cases, many people will encounter such a dilemma, then let the editor lead you to learn how to deal with these situations." I hope you can read it carefully and be able to achieve something!
Related nouns
Authentication and Authorization are so alike that they can't tell them apart.
Authentication (authentication): identifies the identity of the user, which usually occurs when logging in.
Authorization (Authorization): Grant user permission to specify which resources the user can access; authorization requires knowing who the user is, so authorization must be after authentication.
Basic steps of authentication (Authentication)
Install related Nuget packages: Microsoft.AspNetCore.Authentication.JwtBearer
Prepare configuration information (key, etc.)
Add Servic
Call middleware
Implement a JwtHelper to generate Token
Controller restricts access (adds Authorize tags)
1 install the Nuget package
Install Microsoft.AspNetCore.Authentication.JwtBearer
In the package Manager console:
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer-Version 6.0.12 prepare configuration information
In appsetting.json, add a Jwt node
"Jwt": {"SecretKey": "lisheng741@qq.com", "Issuer": "WebAppIssuer", "Audience": "WebAppAudience"} 3 add services
Register the service in the Program.cs file.
/ / introduce the required namespace using Microsoft.AspNetCore.Authentication.JwtBearer;using Microsoft.IdentityModel.Tokens;using System.Text;//... Var configuration = builder.Configuration;// registration service builder.Services.AddAuthentication (options = > {options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme }) .AddJwtBearer (options = > {options.TokenValidationParameters = new TokenValidationParameters () {ValidateIssuer = true, / / whether to verify Issuer ValidIssuer = configuration ["Jwt:Issuer"], / / issuer Issuer ValidateAudience = true, / / whether to verify Audience ValidAudience = configuration ["Jwt:Audience"], / / subscriber Audience ValidateIssuerSigningKey = true / / whether to verify SecurityKey IssuerSigningKey = new SymmetricSecurityKey (Encoding.UTF8.GetBytes (configuration ["Jwt:SecretKey"])), / / SecurityKey ValidateLifetime = true, / / whether to verify failure time ClockSkew = TimeSpan.FromSeconds (30), / / expiration time fault tolerance value Solve the problem of server-side time asynchrony (seconds) RequireExpirationTime = true,} }); 4 call middleware
Calling UseAuthentication (authentication) must be called before all middleware that requires authentication, such as UseAuthorization (authorization).
/ /. App.UseAuthentication (); app.UseAuthorization (); / /. 5 JwtHelper class implementation
It is mainly the Token used to generate JWT.
Using Microsoft.IdentityModel.Tokens;using System.IdentityModel.Tokens.Jwt;using System.Security.Claims;using System.Text;namespace TestWebApi;public class JwtHelper {private readonly IConfiguration _ configuration; public JwtHelper (IConfiguration configuration) {_ configuration = configuration;} public string CreateToken () / / 1. Define Claims var claims = new [] {new Claim (ClaimTypes.Name, "u_admin"), / / HttpContext.User.Identity.Name new Claim (ClaimTypes.Role, "r_admin"), / / HttpContext.User.IsInRole ("r_admin") new Claim (JwtRegisteredClaimNames.Jti, "admin"), new Claim ("Username", "Admin") to be used New Claim ("Name", "Super Admin")} / / 2. Read SecretKey var secretKey = new SymmetricSecurityKey (Encoding.UTF8.GetBytes (_ configuration ["Jwt:SecretKey"])) from appsettings.json; / / 3. Select the encryption algorithm var algorithm = SecurityAlgorithms.HmacSha256; / / 4. Generate Credentials var signingCredentials = new SigningCredentials (secretKey, algorithm); / / 5. According to the above Generate token var jwtSecurityToken = new JwtSecurityToken (_ configuration ["Jwt:Issuer"], / / Issuer _ configuration ["Jwt:Audience"], / / Audience claims, / / Claims, DateTime.Now, / / notBefore DateTime.Now.AddSeconds (30) / / expires signingCredentials / / Credentials) / / 6. Change token to string var token = new JwtSecurityTokenHandler () .WriteToken (jwtSecurityToken); return token;}
The JwtHelper relies on IConfiguration (to read the configuration file). The creation of the JwtHelper is handed over to the DI container, and the service is added to the Program.cs:
Var configuration = builder.Configuration;builder.Services.AddSingleton (new JwtHelper (configuration))
Register JwtHelper as singleton mode.
6 Controller configuration
Create a new AccountController, inject JwtHelper as a constructor, and add two Action:GetToken to get the Token,GetTest and label it with [Authorize] to verify the authentication.
Using Microsoft.AspNetCore.Authorization;using Microsoft.AspNetCore.Mvc;namespace TestWebApi.Controllers; [Route ("api/ [controller] / [action]")] [ApiController] public class AccountController: ControllerBase {private readonly JwtHelper _ jwtHelper; public AccountController (JwtHelper jwtHelper) {_ jwtHelper = jwtHelper;} [HttpGet] public ActionResult GetToken () {return _ jwtHelper.CreateToken () } [Authorize] [HttpGet] public ActionResult GetTest () {return "Test Authorize";}} 7 Test call
Method 1: debug software through Postman, Apifox and other interfaces
Use Postman call / api/Account/GetToken to generate Token
Input Token when calling / api/Account/GetTest to get the returned result
Method 2: debug in the browser console
Debug / api/Account/GetToken
Var xhr = new XMLHttpRequest (); xhr.addEventListener ("readystatechange", function () {if (this.readyState = 4) {console.log (token = this.responseText); / / A global variable token is used here to serve the next interface}}); xhr.open ("GET", "/ api/Account/GetToken"); xhr.send ()
Debug / api/Account/GetTest
Var xhr = new XMLHttpRequest (); xhr.addEventListener ("readystatechange", function () {if (this.readyState = 4) {console.log (this.status, this.responseText); / / this.status: response status code, 401: no authentication status}}); xhr.open ("GET", "/ api/Account/GetTest"); xhr.setRequestHeader ("Authorization", `Bearer ${token} `); / / attached with tokenxhr.send (); Authorization (Authorization)
Note: authorization must be based on authentication, that is, if the above configuration of authentication is not completed, the following authorization will not be successful.
In the authorization part, we will first introduce the relevant labels and authorization methods, and then introduce the policy-based authorization. The general contents of these three parts are as follows:
Related tags: Authorize and AllowAnonymous
Authorization method: introduce the basic contents of Policy, Role and Scheme
Policy-based (Policy) authorization: in-depth Policy authorization
Related tags (Attribute)
For more information about authorization tags, please refer to the official documentation for simple authorization.
[Authorize]
The Controller or Action with this label must be authenticated and can identify which authorization rules need to be met.
Authorization rules can be Policy (policy), Roles (role), or AuthenticationSchemes (scheme).
[Authorize (Policy = ", Roles =", AuthenticationSchemes =")]
[AllowAnonymous]
Anonymous access is allowed at a level higher than [Authorize]. If both work together, it will take effect [AllowAnonymous].
Authorization mode
Basically, there are only three ways of authorization: Policy, Role and Scheme, corresponding to the three attributes of the Authorize tag.
1 Policy (Policy)
The recommended authorization method is most frequently mentioned in the official documentation of ASP.NET Core. A Policy can contain multiple requirements (the requirements may be Role matching, Claims matching, or other ways. )
The following is a basic example (it is a basic example, mainly because some configurations can be added to the authorization method based on Policy):
In Program.cs, add two Policy:
Policy1 requires the user to have a Claim whose ClaimType value is EmployeeNumber.
Policy2 requires the user to have a Claim with a ClaimType value of EmployeeNumber and a ClaimValue value of 1, 2, 3, 4, or 5.
Builder.Services.AddAuthorization (options = > {options.AddPolicy ("policy1", policy = > policy.RequireClaim ("EmployeeNumber")); options.AddPolicy ("policy2", policy = > policy.RequireClaim ("EmployeeNumber", "1", "2", "3", "4", "5");})
Add the [Authorize] tag to the controller to take effect:
[Authorize (Policy = "policy1")] public class TestController: ControllerBase
Or on the Action of the controller:
Public class TestController: ControllerBase {[Authorize (Policy = "policy1")] public ActionResult GetTest = > "GetTest";} 2 Role (role)
Based on role authorization, as long as the user has a role, it can pass authorization verification.
When authenticating, add a role-related Claim to the user to identify the roles the user has (Note: a user can have multiple roles of Claim), such as:
New Claim (ClaimTypes.Role, "admin"), new Claim (ClaimTypes.Role, "user")
In Controller or Action:
[Authorize (Roles = "user")] public class TestController: ControllerBase {public ActionResult GetUser = > "GetUser"; [Authorize (Roles = "admin")] / / superimposed with the Authorize of the controller, in addition to having user, you also need to have admin public ActionResult GetAdmin = > "GetAdmin"; [Authorize (Roles = "user,admin")] / / user or admin can satisfy public ActionResult GetUserOrAdmin = > "GetUserOrAdmin";} 3 Scheme (scheme)
Solutions such as Cookies and Bearer, of course, can also be custom solutions.
As this method is not commonly used, we will not expand it here. Please refer to the official documentation to restrict the identification according to the scheme.
Policy-based (Policy) authorization
A basic example of policy-based authorization has been mentioned above, and this method of authorization will be further explored below.
1 Authorization process
Before delving further into Policy authorization, it is necessary to describe the authorization process. It is recommended that the authorization process description be viewed in conjunction with the source code, so that the role of it can be more clearly. Of course, this part is difficult to understand, the author's expression may not be clear enough, and this part will not affect the configuration of the authorization, so if the reader does not understand or can not understand, you can skip it temporarily and do not have to struggle.
It is recommended to take a look at ASP.NET Core's method of using JWT authentication and authorization, which collates the source code related to authorization and explains the relationship among them.
Here's a quick tease:
The interface and class related to authorization are as follows:
IAuthorizationService # verifies the authorized service. The default implementation of the main method AuthorizeAsyncDefaultAuthorizationService # IAuthorizationService, IAuthorizationHandler #, is responsible for checking whether the requirements are met. The main method HandleAsyncIAuthorizationRequirement # has only attributes and no methods; it is used to mark the service, and the mechanism used to track whether the authorization is successful. AuthorizationHandler # main method HandleRequirementAsync
The relationship between interface and class and the authorization process are as follows:
DefaultAuthorizationService implements the AuthorizeAsync method of IAuthorizationService.
The AuthorizeAsync method gets all the instances that implement IAuthorizationHandler, and iteratively calls the HandleAsync method of all instances to check whether the authorization requirements are met. If any HandleAsync returns Fail, the loop ends (for details, please refer to the official document handler to return the result), and user access is prohibited.
The role of IAuthorizationHandler, as described in the previous point, provides a HandleAsync method for checking authorization.
IAuthorizationRequirement is a requirement, mainly used with AuthorizationHandler.
AuthorizationHandler implements the HandleAsync method of IAuthorizationHandler and provides a method of HandleRequirementAsync. HandleRequirementAsync is used to check whether the Requirement (requirement) is met. The default implementation of HandleAsync is to get all requests that implement TRequirement (and this request is added to the list by Policy) and call HandleRequirementAsync in a loop to check which requirement (Requirement) meets the authorization.
Briefly:
When the [Authorize] tag takes effect, the AuthorizeAsync of IAuthorizationService (implemented by DefaultAuthorizationService) is called.
AuthorizeAsync invokes all IAuthorizationHandler's HandleAsync (implemented by AuthorizationHandler).
HandleAsync will call the HandleRequirementAsync method of AuthorizationHandler.
Note: only the main interfaces and classes are listed here, but some are not listed, such as IAuthorizationHandlerProvider (the default implementation of this interface, DefaultAuthorizationHandlerProvider, is mainly used to collect IAuthorizationHandler and return IEnumerable)
2 implementation description
IAuthorizationService has been implemented by default and no extra work is required for us.
IAuthorizationHandler is implemented by AuthorizationHandler.
So what we need to do is:
The first step is to prepare Requirement to implement IAuthorizationRequirement
The second step is to add a Handler program that inherits AuthorizationHandler and overrides the HandleRequirementAsync method
3 define permission entry
Before implementing Requirement, we need to define some permission entries, which are mainly used as the name of the Policy and passed into the Requirement that we implement.
Public static class UserPermission {public const string User = "User"; public const string UserCreate = User + ".Create"; public const string UserDelete = User + ".Delete"; public const string UserUpdate = User + ".Update";}
As above, permissions such as "add", "delete" and "change" are defined, in which User will have full permissions.
4 implement Requirementpublic class PermissionAuthorizationRequirement: IAuthorizationRequirement {public PermissionAuthorizationRequirement (string name) {Name = name;} public string Name {get; set;}}
Use the Name attribute to represent the name of the permission, which corresponds to the constant in UserPermission.
5 implement the authorization handler Handler
It is assumed that the ClaimType in the user's Claim is Permission, such as:
New Claim ("Permission", UserPermission.UserCreate), new Claim ("Permission", UserPermission.UserUpdate)
As above, identify the permissions of the user UserCreate and UserUpdate.
Note: of course, the actual program is certainly not implemented in this way, here is just a simple example.
Next, implement an authorization Handler:
Public class PermissionAuthorizationHandler: AuthorizationHandler {protected override Task HandleRequirementAsync (AuthorizationHandlerContext context, PermissionAuthorizationRequirement requirement) {var permissions = context.User.Claims.Where (_ = > _ .Type = = "Permission"). Select (_ = > _ .Value). ToList (); if (permissions.Any (_ = > _ .Startswith (requirement.Name) {context.Succeed (requirement);} return Task.CompletedTask;}}
When running HandleRequirementAsync, the items in the user's Claim whose ClaimType is Permission are taken out and their Value is obtained to form a List.
Then verify that the Requirement meets the authorization, and run context.Succeed if it does.
6 add authorization handler
In Program.cs, add PermissionAuthorizationHandler to DI:
Builder.Services.AddSingleton (); 7 add authorization policy builder.Services.AddAuthorization (options = > {options.AddPolicy (UserPermission.UserCreate, policy = > policy.AddRequirements (new PermissionAuthorizationRequirement (UserPermission.UserCreate); options.AddPolicy (UserPermission.UserUpdate, policy = > policy.AddRequirements (new PermissionAuthorizationRequirement (UserPermission.UserUpdate); options.AddPolicy (UserPermission.UserDelete, policy = > policy.AddRequirements (new PermissionAuthorizationRequirement (UserPermission.UserDelete));}); 8 Controller configuration
The controller is as follows:
[Route ("api/ [controller] / [action]")] [ApiController] public class UserController: ControllerBase {[HttpGet] [Authorize (UserPermission.UserCreate)] public ActionResult UserCreate () = > "UserCreate"; [HttpGet] [Authorize (UserPermission.UserUpdate)] public ActionResult UserUpdate () = > "UserUpdate"; [HttpGet] [Authorize (UserPermission.UserDelete)] public ActionResult UserDelete () = > "UserDelete";}
Based on the above assumptions, the user access interface is as follows:
/ api/User/UserCreate # success / api/User/UserUpdate # success / api/User/UserDelete # 403 No permission
At this point, policy-based (Policy) authorization is actually almost complete.
The next content will be the improvement or supplement to some of the above.
Perfection: implementing the policy provider PolicyProvider
Generally, the authorization policy is added as follows in Program.cs:
Builder.Services.AddAuthorization (options = > {options.AddPolicy ("policy", policy = > policy.RequireClaim ("EmployeeNumber");})
Adding authorization policies through AuthorizationOptions.AddPolicy is inflexible and cannot be added dynamically.
By implementing IAuthorizationPolicyProvider and adding it to DI, you can add Policy dynamically.
The default implementation of IAuthorizationPolicyProvider is DefaultAuthorizationPolicyProvider.
Implement a PolicyProvider as follows:
Public class TestAuthorizationPolicyProvider: DefaultAuthorizationPolicyProvider, IAuthorizationPolicyProvider {public Test2AuthorizationPolicyProvider (IOptions options): base (options) {} public new Task GetDefaultPolicyAsync () = > return base.GetDefaultPolicyAsync (); public new Task GetFallbackPolicyAsync () return base.GetFallbackPolicyAsync (); public new Task GetPolicyAsync (string policyName) {if (policyName.StartsWith (UserPermission.User)) {var policy = new AuthorizationPolicyBuilder ("Bearer"); policy.AddRequirements (new PermissionAuthorizationRequirement (policyName)) Return Task.FromResult (policy.Build ());} return base.GetPolicyAsync (policyName);}}
Note: custom TestAuthorizationPolicyProvider must implement IAuthorizationPolicyProvider, otherwise it will not take effect when added to DI.
In Program.cs, add a custom PolicyProvider to the DI:
Builder.Services.AddSingleton ()
Note: only the last added PolicyProvider will take effect.
Supplement: custom AuthorizationMiddleware
Custom AuthorizationMiddleware can:
Returns a custom response
Enhance (or change) the default challenge or forbid response
Supplement: authorization of MiniApi
In MiniApi, there are almost all branch nodes in the shape of MapGet (). Such endpoints cannot use the [Authorize] tag, but can be authorized by using RequireAuthorization ("Something"), such as:
App.MapGet ("/ helloworld", () = > "Hello World!") .RequireAuthorization ("AtLeast21"); "ASP.NET Core 6.0How to add JWT authentication and authorization" is introduced here, thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 295
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.