认证和授权区别?
首先我们要弄清楚认证(Authentication)和授权(Authorization)的区别,以免混淆了。认证是确认的过程中你是谁,而授权围绕是你被允许做什么,即权限。显然,在确认允许用户做什么之前,你需要知道他们是谁,因此,在需要授权时,还必须以某种方式对用户进行身份验证。
什么是JWT?
根据维基百科的定义,JSON WEB Token(JWT),是一种基于JSON的、用于在网络上声明某种主张的令牌(token)。JWT通常由三部分组成:头信息(header),消息体(payload)和签名(signature)。
头信息指定了该JWT使用的签名算法:
header = '{"alg":"HS256","typ":"JWT"}'
HS256
表示使用了HMAC-SHA256来生成签名。
消息体包含了JWT的意图:
payload = '{"loggedInAs":"admin","iat":1422779638}'//iat表示令牌生成的时间
未签名的令牌由base64url
编码的头信息和消息体拼接而成(使用"."分隔),签名则通过私有的key计算而成:
key = 'secretkey' unsignedToken = encodeBase64(header) + '.' + encodeBase64(payload) signature = HMAC-SHA256(key, unsignedToken)
最后在未签名的令牌尾部拼接上base64url
编码的签名(同样使用"."分隔)就是JWT了:
token = encodeBase64(header) + '.' + encodeBase64(payload) + '.' + encodeBase64(signature) # token看起来像这样: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI
JWT常常被用作保护服务端的资源(resource),客户端通常将JWT通过HTTP的Authorization
header发送给服务端,服务端使用自己保存的key计算、验证签名以判断该JWT是否可信:
Authorization: Bearer eyJhbGci*...<snip>...*yu5CSpyHI
接下来进入正题:
1、NuGet
Microsoft.AspNetCore.Authentication.JwtBearer
2、Startup.cs文件ConfigureServices方法
1 services.AddAuthentication(options => 2 { 3 options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; 4 options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 5 options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; 6 }).AddJwtBearer(options => 7 { 8 options.SaveToken = true; 9 options.RequireHttpsMetadata = false; 10 options.TokenValidationParameters = new TokenValidationParameters() 11 { 12 ValidateIssuer = true, 13 ValidateAudience = true, 14 ValidAudience = "https://www.cnblogs.com/chengtian", 15 ValidIssuer = "https://www.cnblogs.com/chengtian", 16 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecureKeySecureKeySecureKeySecureKeySecureKeySecureKey")) 17 }; 18 });
2、修改 Configure方法
app.UseAuthentication();//认证中间件
3、添加获取token方法
1 [Route("api/[controller]")] 2 public class AuthenticateController : Controller 3 { 4 [HttpPost] 5 [Route("login")] 6 public IActionResult Login([FromBody]LoginInput input) 7 { 8 //从数据库验证用户名,密码 9 //验证通过 否则 返回Unauthorized 10 11 //创建claim 12 var authClaims = new[] { 13 new Claim(JwtRegisteredClaimNames.Sub,input.Username), 14 new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()) 15 }; 16 IdentityModelEventSource.ShowPII = true; 17 //签名秘钥 可以放到json文件中 18 var authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("SecureKeySecureKeySecureKeySecureKeySecureKeySecureKey")); 19 20 var token = new JwtSecurityToken( 21 issuer: "https://www.cnblogs.com/chengtian", 22 audience: "https://www.cnblogs.com/chengtian", 23 expires: DateTime.Now.AddHours(2), 24 claims: authClaims, 25 signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256) 26 ); 27 28 //返回token和过期时间 29 return Ok(new 30 { 31 token = new JwtSecurityTokenHandler().WriteToken(token), 32 expiration = token.ValidTo 33 }); 34 } 35 }
4、使用
在需要认证的接口上添加过滤器就行了
注意:
感谢:
https://www.cnblogs.com/chengtian/p/11927663.html