ASP.NET Core 3.0 Lightweight role of a jwt / user, a single API control of authorized authentication library

Explanation

ASP.NET Core 3.0 Lightweight role of a jwt / user, a single API control of authorized authentication library

Recently was empty, authorize re-do a role, but a role authorization before making the library is using Microsoft's default interface to do, a lot of access to documents, because understanding is not enough, so in the end made a problem.

The old version before https://github.com/whuanle/CZGL.Auth/tree/1.0.0

If you are using Microsoft's default interface, I personally think is too complicated, but also for the information in this section is less. . .

Use the default authorization and authentication interface, you can refer to my other article

ASP.NET Core Interface JWT using custom roles / policy authorization to be achieved

Thanks to large guide Benxiong brother, the use of vacation time to do a re-use of Microsoft's own certification authority, on this basis do expand. Characterized by the use of very simple, without excessive configuration; because they would not "create the wheel," so if in need of rehabilitation, but also very simple.

This library update to .Net Core 3.0, and if you need to use on the 2.2X, you can download the project to the warehouse and then pack into Nuget 2.2.

Big thanks to the guidance of Benxiong brother.

Project warehouse address https://github.com/whuanle/CZGL.Auth

First, define roles, API, user

Just create a website or API project, such as MyAuth.

Nuget in search CZGL.Auth, in accordance with the 2.0.1 version, or use the Package Manager command

Install-Package CZGL.Auth -Version 2.0.1

CZGL.Auth design idea is that the site can be multiple roles, multiple users, multiple API,

A role has some of the API, you can add or delete roles or modify the API access of the role of ownership;

A user can belong to several roles at the same time.

The first step to consider the role of the site, user, API design,

CZGL.Auth this information stored in memory, a user that has several roles, access rights, which the API has a role.

API is a role with the correspondence between users with role-many relationship.

Create a new class RoleService.cs, introduction using CZGL.Auth.Services;, RoleService inherited ManaRole.

By the following interface operations role permissions information

        protected bool AddRole(RoleModel role);
        protected bool AddUser(UserModel user);
        protected bool RemoveRole(string roleName);
        protected bool RemoveUser(string userName);

Clearly, add / remove a role, add / remove a user

If there are A, B, C three roles,
there are / A, / B, / C , / AB, / AC, / BC, / ABC total of seven the API, setting authority

A can access the A, AB, AC, ABC

B can be accessed B, AB, BC, ABC

C can access C, AC, BC, ABC

Here analog process data, from the database without loading the actual data inside.

A method in which increasing RoleService

        /// <summary>
        /// 用于加载角色禾API
        /// </summary>
        public void UpdateRole()
        {
            List<RoleModel> roles = new List<RoleModel>
            {
                new RoleModel
                {
                    RoleName="A",
                    Apis=new List<OneApiModel>
                    {
                        new OneApiModel
                        {
                            ApiName="A",
                            ApiUrl="/A"
                        },
                        new OneApiModel
                        {
                            ApiName="AB",
                            ApiUrl="/AB"
                        },
                        new OneApiModel
                        {
                            ApiName="AC",
                            ApiUrl="/AC"
                        },
                        new OneApiModel
                        {
                            ApiName="ABC",
                            ApiUrl="/ABC"
                        }
                    }
                },
                new RoleModel
                {
                    RoleName="B",
                    Apis=new List<OneApiModel>
                    {
                        new OneApiModel
                        {
                            ApiName="B",
                            ApiUrl="/B"
                        },
                        new OneApiModel
                        {
                            ApiName="AB",
                            ApiUrl="/AB"
                        },
                        new OneApiModel
                        {
                            ApiName="BC",
                            ApiUrl="/BC"
                        },
                        new OneApiModel
                        {
                            ApiName="ABC",
                            ApiUrl="/ABC"
                        }
                    }
                },
                new RoleModel
                {
                    RoleName="A",
                    Apis=new List<OneApiModel>
                    {
                        new OneApiModel
                        {
                            ApiName="A",
                            ApiUrl="/A"
                        },
                        new OneApiModel
                        {
                            ApiName="AB",
                            ApiUrl="/AB"
                        },
                        new OneApiModel
                        {
                            ApiName="AC",
                            ApiUrl="/AC"
                        },
                        new OneApiModel
                        {
                            ApiName="ABC",
                            ApiUrl="/ABC"
                        }
                    }
                }
            };
            foreach (var item in roles)
            {
                AddRole(item);
            }

        }

With the API information corresponding role Wo, it is necessary to add a user,

Suppose there are aa, bb, cc three users, password is 123456, aa role belongs to A, bb role belongs to B ...

        public void UpdateUser()
        {
            AddUser(new UserModel { UserName = "aa", BeRoles = new List<string> { "A" } });
            AddUser(new UserModel { UserName = "bb", BeRoles = new List<string> { "B" } });
            AddUser(new UserModel { UserName = "cc", BeRoles = new List<string> { "C" } });
        }

In order to be able to user roles and loaded into CZGL.Auth, you need when the program starts, for example in the Program, the use of

            RoleService roleService = new RoleService();
            roleService.UpdateRole();
            roleService.UpdateUser();

Second, add custom events

Authorization is, there may be a variety of situations, you can add custom events authorization information record user access authorization affect the results.

Quote using CZGL.Auth.Interface;,

Add a class inherits IRoleEventsHadner RoleEvents

    public class RoleEvents : IRoleEventsHadner
    {
        public async Task Start(HttpContext httpContext)
        {
            await Task.CompletedTask;
        }
        public void TokenEbnormal(object eventsInfo)
        {
        }
        public void TokenIssued(object eventsInfo)
        {
        }
        public void NoPermissions(object eventsInfo)
        {
        }
        public void Success(object eventsInfo)
        {
        }
        public async Task End(HttpContext httpContext)
        {
            await Task.CompletedTask;
        }
    }

Call before CZGL.Auth start verifying authorization Start, End call at the end, passing the parameters are passed HttpContext types, you can add a custom message on the inside of the authorization, which may affect the request pipeline.

Several other methods have the following meanings:

TokenEbnormal client carried Token is not valid Jwt token, it will not be resolved

After TokenIssued decoded token, issuer or incorrect audience

NoPermissions not authorized to access this API

We will call the above method at various stages of the certification authority.

Third, the injection of authorized service and middleware

Use CZGL.Auth, you need to inject the following two services

            services.AddRoleService(authOptions);
            services.AddSingleton<IRoleEventsHadner, RoleEvents>();

AddRoleServiceIs injected into the authorization service, AddSingletoninject your event.

AddRoleService need a AuthConfigModel type as a parameter.

You can configure this

            var authOptions = new AuthBuilder()
                .Security("aaaafsfsfdrhdhrejtrjrt", "ASPNETCORE", "ASPNETCORE")
                .Jump("accoun/login", "account/error", false, false)
                .Time(TimeSpan.FromMinutes(20))
                .InfoScheme(new CZGL.Auth.Models.AuthenticateScheme
                {
                    TokenEbnormal = "Login authentication failed!",
                    TokenIssued = "Login authentication failed!",
                    NoPermissions = "Login authentication failed!"
                }).Build();
            services.AddRoleService(authOptions);

            services.AddSingleton<IRoleEventsHadner, RoleEvents>();

Security configuration key related parameters are key string, the issuer, subscribers.

When Jump configure authorization fails, the jump address. When the parameters are not authorized to jump, jump invalid license, the latter two may be provided bool jump or jump.

Time Configuration Token is valid.

InfoScheme authorization failure message, for example,

FIG time expired on the prompt message, return a status code 401 when a user API request fails, prompt message carries Header, CZGL.Auth set inside the three cases, custom header:

TokenEbnormal client carried Token is not valid Jwt token, it will not be resolved

After TokenIssued decoded token, issuer or incorrect audience

NoPermissions not authorized to access this API

Add three middleware

            app.UseAuthentication();
            app.UseAuthorization();
            app.UseMiddleware<RoleMiddleware>();

app.UseAuthorization();Microsoft licensed certified middleware, CZGL.Auth would let the default authentication pipe filter some invalid request and authentication information, and then by CZGL.Auth to verify authorization.

Third, how to set up the authorization API

Very simple, CZGL.Auth authentication and authorization, you just add on a Controller or Action [Authorize].

CZGL.Auth will only use the [Authorize]entry into force characteristics of the Controller or Action.

If a Controller has been set [Authorize], but you want to skip the inside of the Action authorization certification, the use of [AllowAnonymous]modified Action.

Use exactly the same with the default Microsoft. So without too much configuration.

If you want another to define a characteristic set for another authorization, then I can go to the warehouse or directly contact me mention Issue micro letter.

Add a APIController,

    [Authorize]
    [Route("api/[controller]")]
    [ApiController]
    public class TestController : ControllerBase
    {

        [HttpGet("/A")]
        public JsonResult A()
        {
            return new JsonResult(new { Code = 200, Message = "Success!" });
        }

        [HttpGet("/B")]
        public JsonResult B()
        {
            return new JsonResult(new { Code = 200, Message = "Success!" });
        }

        [HttpGet("/C")]
        public JsonResult C()
        {
            return new JsonResult(new { Code = 200, Message = "Success!" });
        }
        [HttpGet("/AB")]
        public JsonResult AB()
        {
            return new JsonResult(new { Code = 200, Message = "Success!" });
        }
        [HttpGet("/BC")]
        public JsonResult BC()
        {
            return new JsonResult(new { Code = 200, Message = "Success!" });
        }
        [HttpGet("/AC")]
        public JsonResult AC()
        {
            return new JsonResult(new { Code = 200, Message = "Success!" });
        }

        [HttpGet("/ABC")]
        public JsonResult ABC()
        {
            return new JsonResult(new { claims = User.Claims });
        }


        /// <summary>
        /// 任何人都不能访问
        /// </summary>
        /// <returns></returns>
        [HttpGet("D")]
        public JsonResult D()
        {
            return new JsonResult(new { Code = 200, Message = "Success!" });
        }

        [HttpGet("error")]
        public JsonResult Denied()
        {
            return new JsonResult(
                new
                {
                    Code = 0,
                    Message = "访问失败!",
                    Data = "此账号无权访问!"
                });
        }
    }

Fourth, add a login issue Token

Add a AccountController.cs awarded to log in, Token.

    [Route("api/[controller]")]
    [ApiController]
    public class AccountController : ControllerBase
    {
        [HttpPost("/Login")]
        public async Task<JsonResult> Login([FromQuery]string username, string password, string rolename)
        {
            // 用户名密码是否正确
            if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password) || string.IsNullOrWhiteSpace(rolename))
            {
                return new JsonResult(new 
                {
                    Code = 0,
                    Message = "尼玛,上传什么垃圾信息",
                });
            }

            if(!((username=="aa"||username=="bb"||username=="cc")&&password=="123456"))
            {
                return new JsonResult(new
                {
                    Code = 0,
                    Message = "账号或密码错误",
                });
            }

            // 你自己定义的角色/用户信息服务
            RoleService roleService = new RoleService();

            // 检验用户是否属于此角色
            var role = roleService.IsUserToRole(username,rolename);

            // CZGL.Auth 中一个用于加密解密的类
            EncryptionHash hash = new EncryptionHash();

            // 设置用户标识
            var userClaims = hash.BuildClaims(username, rolename);

            //// 自定义构建配置用户标识
            /// 自定义的话,至少包含如下标识
            //var userClaims = new Claim[]
            //{
            //new Claim(ClaimTypes.Name, userName),
            //    new Claim(ClaimTypes.Role, roleName),
            //    new Claim(JwtRegisteredClaimNames.Aud, Audience),
            //    new Claim(ClaimTypes.Expiration, TimeSpan.TotalSeconds.ToString()),
            //    new Claim(JwtRegisteredClaimNames.Iat, new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds().ToString())
            //};
            /*
            iss (issuer):签发人
            exp (expiration time):过期时间
            sub (subject):主题
            aud (audience):受众
            nbf (Not Before):生效时间
            iat (Issued At):签发时间
            jti (JWT ID):编号
            */

            // 方法一,直接颁发 Token
            ResponseToken token = hash.BuildToken(userClaims);


            //方法二,拆分多步,颁发 token,方便调试
            //var identity = hash.GetIdentity(userClaims);
            //var jwt = hash.BuildJwtToken(userClaims);
            //var token = hash.BuildJwtResponseToken(jwt);

            return new JsonResult(token);
        }
    }

Fifth, part of the explanation

Injection Jwt service, issued Token

CZGL.Auth to use jwt services and Token code issued by a good package, this library is not in the "create the wheel," so in fact you can easily come out of this part of the code, in addition to design.

Code Location RoleServiceExtension.cs this part, EncryptionHash.cs.

Authorized Middleware

            app.UseAuthentication();
            app.UseAuthorization();
            app.UseMiddleware<RoleMiddleware>();

My writing is to use ASP.NET Core of jwt complete authentication and authorization based, then the next expansion of the pipeline to achieve certification. But the certification itself is in app.UseAuthorization (); do expand, so use CZGL.Auth, only need to follow the usual jwt way to use, just add a RoleMiddleware middleware.

CZGL.Auth I was just inspired by new ideas temporarily written out. . . It is best not used directly for production, github repository to download the project, according to its own application scenarios change it ~.

Sixth, verification

First use aa user logs in, select A role login.

Because A user can only access the API "with A" is, "/ A", "/ AB" and so on, so we can try.

Token continue to use this visit at "/ B"

You can continue to try to add API or using other user logs in, different access API.

Because someone unfamiliar to the front, so I will not write a page with examples of the ~.

Postman test can be used on the line.

Examples of what the project can be downloaded to the warehouse, the name is MyAuth.

Generally, user rights, roles, permissions information in a database, the storage is another example of CZGL.Auth.Sample2.

This library is just a more sketchy authorization and authentication, and richer needs to download the source code, please modify ~

There are issues to be discussed, I can be found inside the club.

Shenzhen, Guangzhou, Changsha, Shanghai and other group I have been, hey hey hey, hey hey hey.

Guess you like

Origin www.cnblogs.com/whuanle/p/11743406.html