zoukankan      html  css  js  c++  java
  • .Net Core WebApi 使用 JWT 验证身份

    一、注册身份验证服务

      StartUp.ConfigureServices()

        //策略授权
        services.AddAuthorization(options =>
        {
            options.AddPolicy("Admin", po => po.RequireRole("Admin"));
            options.AddPolicy("Client", policy => policy.RequireRole("Client"));
            options.AddPolicy("Systems", policy => policy.RequireRole("Admin", "System", "Client"));
        });
    
        //JWT 身份验证
        services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(setting.SecretKey)),
                ValidateAudience = true,
                ValidAudience = setting.Audience,
                ValidateIssuer = true,
                ValidIssuer = setting.Issuer,
                ClockSkew = TimeSpan.Zero,
                ValidateLifetime = true,
                RequireExpirationTime = true
            };
            options.Events = new JwtBearerEvents
            {
                OnChallenge = context =>
                {
                    //跳过所有默认的逻辑
                    context.HandleResponse();
                    var result = new
                    {
                        status = 401,
                        msg = "无效的Token",
                        err = "无效的Token"
                    };
                    context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                    context.Response.ContentType = "application/json";
                    context.Response.WriteAsync(JsonConvert.SerializeObject(result)); 
                    return Task.CompletedTask;
                }
            };
        });

    二、添加认证中间件(官方定义)

      StartUp.Configure() 

    //这里注意 一定要在 UseMvc前面,顺序不可改变
    app.UseAuthentication(); 
    app.UseMvc();

    三、设置Controller访问权限

      将需要身份验证才可访问的 API 增加验证 [Authorize] ,如果允许匿名访问 ,添加 [AllowAnonymous]

        [Route("api/[controller]")]
        //[ApiExplorerSettings(IgnoreApi = true)]//awagger忽略当前Api
        //[Authorize(Roles = "Admin")] //只允许 用户 Role 是 Admin 可以访问
        //[Authorize] //任何登陆的用户都可以访问
        [Authorize(Policy = "Admin")] //对应 services.AddAuthorization 定义的策略名 
        public class EmployeeController1 : Controller
        {
            /// <summary>
            /// 获取所有员工
            /// </summary>
            /// <returns></returns> 
            [HttpGet]
            public async Task<ResultData<IList<Employee>>> Get()
            {
                var data = await Task.Run(() => GetSourceEmployees());
    var result = new ResultData<IList<Employee>> { Code = (int)ResultCodeEnum.SUCCESS, Msg = "成功", Data = data }; return result; } /// <summary> /// 根据Id 获取员工 /// </summary> /// <param name="id"></param> /// <returns></returns> [HttpGet("{id}")] [AllowAnonymous] //允许匿名访问 public async Task<ResultData<Employee>> Get(int id) { var result = new ResultData<Employee> { Code = (int)ResultCodeEnum.SUCCESS, Msg = "成功", }; var employees = await Task.Run(() => GetSourceEmployees()); var data = employees.FirstOrDefault(l => l.Id == id); if (data != null) { result.Code = (int)ResultCodeEnum.DATA_NULL; result.Msg = "找不到所需数据"; } else { result.Code = (int)ResultCodeEnum.SUCCESS; result.Msg = "成功"; result.Data = data; } return result; } [NonAction] private IList<Employee> GetSourceEmployees() { IList<Employee> employees = new List<Employee>(); employees.Add(new Employee { Address = "北京市朝阳公园", Gender = 1, Id = 1, Mobile = "16578976589", Name = "张三" }); employees.Add(new Employee { Address = "批量添加", Gender = 2, Id = 2, Mobile = "16897623407", Name = "测试员工-001" }); return employees; } }

    四、创建Token

        [Route("api/[controller]")]
        [ApiController]
        public class TokenController : ControllerBase
        {
            JwtSettings setting;//Token 配置信息
            IMerchantRepository _merchantRepository;
    
            //IOptions<JwtSettings> 是在 appsetting.json 的配置项
            //需要提前在 StartUp.ConfigureServices注册 
            public TokenController(IOptions<JwtSettings> jwtSettings, IMerchantRepository merchantRepository)
            {
                setting = jwtSettings.Value;
                _merchantRepository = merchantRepository;
            }
    
            [HttpGet]
            public async Task<IActionResult> Get(string appid, string appsecret)
            {
                try
                {
                    var merchants = await _merchantRepository.LoadAll();
                    var merchant = merchants.FirstOrDefault(l => l.AppId == appid && l.AppSecret == appsecret);
                    if (merchant == null)
                    {
                        return new JsonResult(new
                        {
                            status = 400,
                            msg = "无效的用户",
                            token = string.Empty
                        }); ;
                    }
    
                    var claims = new List<Claim>();
                    claims.Add(new Claim(ClaimTypes.Name, merchant.Name));
                    var roles = merchant.Roles.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < roles.Length; i++)
                    {
                        //添加用户的角色
                        claims.Add(new Claim(ClaimTypes.Role, roles[i]));
                    }
    
                    //SecretKey 必须>= 16位
                    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(setting.SecretKey));
                    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                    //设置 token 生成元素
                    var token = new JwtSecurityToken(
                        issuer: setting.Issuer,
                        audience: setting.Audience,
                        claims: claims,
                        notBefore: DateTime.Now,
                        expires: DateTime.Now.AddSeconds(100),
                        signingCredentials: creds);
                    var result = new JwtSecurityTokenHandler().WriteToken(token);
                    return new JsonResult(new
                    {
                        status = 200,
                        msg = "成功",
                        token = result
                    });
                }
                catch (Exception ex)
                {
                    return new JsonResult(new
                    {
                        status = 500,
                        msg = "服务器开小差了",
                        err = ex.Message
                    });
                }
            }
        }

    五、测试

      1、直接访问 /api/values,出现以下提示

      2、访问 /api/values/1 可正常访问

      3、请求 /api/token,然后添加到 /api/values 的 Headers 再次访问

     

  • 相关阅读:
    hdu 1015 Safecracker 暴力搜索
    hdu 1239 Calling Extraterrestrial Intelligence Again 枚举
    hdu 3747 Download 菜鸟杯
    hdu 3744 A Runing Game 菜鸟杯
    Request.QueryString 使用时候应该注意的地方。
    图片 上一张 下一张 链接效果
    ASP.NET 输出缓存的移除
    RSS 消费
    RSS 订阅功能的实现
    创建型模式单件模式(1)
  • 原文地址:https://www.cnblogs.com/Zing/p/13339039.html
Copyright © 2011-2022 走看看