雪花

二、Core授权-2 之.net core 基于Jwt实现Token令牌(策略)

Authorization其目标就是验证Http请求能否通过验证。ASP.Net Core提供了很多种Authorization方式,详细可以参考 微软官方文档。在这里只详细介绍三种方式:

Policy

Middleware

Custom Attribute

一、Role授权

 代码如下:

#region jwt验证
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidIssuer = Configuration["Jwt:Issuer"],
                ValidAudience = Configuration["Jwt:Audience"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"]))
            };
        });
#endregion

在Claim中设置了Role

所以我们可以将  [Authorize]  标签写成[Authorize(Roles="admin")]

只有解析出来的token中的角色为admin才授权成功,才可以进入方法内,

在new Claim(ClaimTypes.Role, user) //包含类型为Role的Claim。

如果变量名user是Admin通过[Authorize(Roles="admin")]则验证不通过,小写的admin则通过,(区分大小写)

二、Claims授权

1、要使用Claims授权,我们首先需要在Startup.cs的ConfigureServices方法中添加授权

 授权代码:

#region jwt验证
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidIssuer = Configuration["Jwt:Issuer"],
                ValidAudience = Configuration["Jwt:Audience"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"]))
            };
        });
#endregion
#region 授权
services.AddAuthorization(options =>
{
    options.AddPolicy("EmployeeOnly", policy => { policy.RequireClaim("EmployeeNumber"); });
});
//如上,我们定义了一个名称为EmployeeOnly的授权策略,它要求用户的Claims中必须包含类型为EmployeeNumber的Claim。
#endregion

然后在CommonController.cs生成token的action中的Claim中添加EmployeeNumber

 最后在需要权限认证的地方使用标签    [Authorize(Policy="EmployeeOnly")]

我们首先获取一下token,到jwt官网上解析一下发现token中包含EmployeeNumber

 

 然后访问成功

 如果Claim不包含EmployeeNumber类型的,则访问失败。

 访问

 三、自己定制JWT验证(自定义Token获取方式)

自定义类似jwt的token验证,也就是说直接从header中拿取我们想要的token

1、Startup.cs中的ConfigureServices方法中注释掉以下内容,然后自定义jwt token

 代码如下:

            #region jwt验证
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer(options =>
                    {
                        /*options.TokenValidationParameters = new TokenValidationParameters
                        {
                            ValidIssuer = Configuration["Jwt:Issuer"],
                            ValidAudience = Configuration["Jwt:Audience"],
                            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"]))
                        };*/

                        #region 自定义Jwt的token验证
                        options.SecurityTokenValidators.Clear();//将SecurityTokenValidators清除掉,否则它会在里面拿验证
                        options.SecurityTokenValidators.Add(new MyTokenValidator()); //自定义的MyTokenValidator验证方法
                        options.Events = new JwtBearerEvents
                        {
                            //重写OnMessageReceived
                            OnMessageReceived = context =>
                            {
                                var token = context.Request.Headers["mytoken"];
                                context.Token = token.FirstOrDefault();
                                return Task.CompletedTask;
                            }
                        };
                        #endregion

                    });
            #endregion

2、接下来我们新建MyTokenValidator.cs类来验证token,并让这个类实现ISecurityTokenValidator接口

 代码如下:

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace ZanLveCore
{
    public class MyTokenValidator : ISecurityTokenValidator
    {
        bool ISecurityTokenValidator.CanValidateToken => true;

        int ISecurityTokenValidator.MaximumTokenSizeInBytes { get; set; }

        bool ISecurityTokenValidator.CanReadToken(string securityToken)
        {
            return true;
        }

        //验证token
        ClaimsPrincipal ISecurityTokenValidator.ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
        {
            validatedToken = null;
            //判断token是否正确
            if (securityToken != "abcdefg")
                return null;

            //给Identity赋值
            var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
            identity.AddClaim(new Claim("name", "wyt"));
            identity.AddClaim(new Claim(ClaimsIdentity.DefaultRoleClaimType, "admin"));

            var principle = new ClaimsPrincipal(identity);
            return principle;
        }
    }
}

访问成功

 Swagger UI访问

 

 其实这种验证方式是 简称 清除验证规则,自定义验证方式

options.SecurityTokenValidators.Clear();//将SecurityTokenValidators清除掉,否则它会在里面拿验证
options.SecurityTokenValidators.Add(new MyTokenValidator()); //自定义的MyTokenValidator验证方法

还有一种方式是 简称 重写验证方式
权限授权Handler的继承AuthorizationHandler的自定义授权类 




posted @ 2019-12-26 11:05  十色  阅读(1255)  评论(3编辑  收藏  举报