认证是为了验证用户是否合法,即验证用户的认证信息是否正确;受权是验证已经过认证的用户是否具备作某事的权限。咱们这里采用JWT进行认证与受权。api
一个完整的系统一般包含认证与受权,这样只有提供正确认证信息且具备操做权限的用户才能访问该系统,从而实现了对系统的保护。数组
生成一个token令牌:服务器
[HttpGet] public ActionResult<IEnumerable<string>> Get() { // 简单建立一个token令牌 // 建立声明数组 var claims = new Claim[] { new Claim(ClaimTypes.Name, "pwai"), new Claim(JwtRegisteredClaimNames.Email, "pwai@qq.com"), new Claim(JwtRegisteredClaimNames.Sub, "1"),//主题subject,就是id uid }; // 实例化 token 对象 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("winrtwinrtwinrtwinrt"));//至少16位密钥 var token = new JwtSecurityToken( issuer: "http://localhost:5000", // 发行人,就是当前咱们项目 audience: "http://localhost:5001", // 订阅,这是咱们须要哪一个项目去使用这个token claims: claims, expires: DateTime.Now.AddHours(1), signingCredentials: new SigningCredentials(key, SecurityAlgorithms.HmacSha256) ); // 生成token var jwtToken = new JwtSecurityTokenHandler().WriteToken(token); return new string[] { jwtToken }; }
开启 Bearer 认证和注册 JwtBearer :app
public void ConfigureServices(IServiceCollection services) { // 把JwtSecurityTokenn进行清除,net core禁止他进行配置映射JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // 认证逻辑要与前面的生成token令牌的逻辑同样 var symmetricKeyAsBase64 = "winrtwinrtwinrtwinrt"; var keyByteArray = Encoding.ASCII.GetBytes(symmetricKeyAsBase64); var signingKey = new SymmetricSecurityKey(keyByteArray); var tokenValidationParameters = new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = signingKey, ValidateIssuer = true, ValidIssuer = "http://localhost:5000",//发行人 ValidateAudience = true, ValidAudience = "http://localhost:5001",//订阅人 ValidateLifetime = true, ClockSkew = TimeSpan.FromSeconds(30), RequireExpirationTime = true, }; services.AddAuthentication("Bearer") .AddJwtBearer(o => { o.TokenValidationParameters = tokenValidationParameters; }); }
开启受权中间件:ide
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { //方法上下文省略了其余中间件 app.UseAuthentication(); }
获取token令牌:post
[HttpGet("{jwtStr}")] [Authorize] //受权 public ActionResult<IEnumerable<string>> Get(string jwtStr) { // 获取token内容的方法 // 方法一 var jwtHandler = new JwtSecurityTokenHandler(); JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr); // 方法二 var sub = User.FindFirst(d => d.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name")?.Value; // 方法三 var name = _accessor.HttpContext.User.Identity.Name; var claims= _accessor.HttpContext.User.Claims; var claimTypeVal= (from item in claims where item.Type == JwtRegisteredClaimNames.Email select item.Value).ToList(); return new string[] { JsonConvert.SerializeObject(jwtToken), sub, name, JsonConvert.SerializeObject(claimTypeVal) }; }
使用postman测试:
请求http://localhost:5000/api/Values/ ,获取token测试
请求http://localhost:5000/api/Values/(复制刚刚获取的token)eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoicHdhaSIsImVtYWlsIjoicHdhaUBxcS5jb20iLCJzdWIiOiIxIiwiZXhwIjoxNjA2MDYyMTM4LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjUwMDAiLCJhdWQiOiJodHRwOi8vbG9jYWxob3N0OjUwMDEifQ.quIqR-OBWXiPJ8r3myymrqztg5Bd1xyIfIl0P_Whuncui
同时在请求信息头中加入http认证,当客户端使用指定的认证方式,并提供正确的认证信息时,即在请求消息头中添加Authorization项,此时再访问该资源,服务器会对用户提供的信息进行验证。
bearer认知使用格式:Authorization: Bearer <bearer_token>
spa
发送请求,能够查看到序列化token结果:pwa