一、注册身份验证服务
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 再次访问