代码我参考了一本书 Modern API Design with ASP.NET Core 2 Building Cross-Platform Back-End Systems
网上也有一个很牛 https://jasonwatmore.com/post/2018/08/14/aspnet-core-21-jwt-authentication-tutorial-with-example-api
1.获取token 的controller
1 [HttpGet] 2 public IActionResult GetToken() 3 { 4 var authorizationHeader = Request.Headers["Authorization"].First(); 5 var key = authorizationHeader.Split(' ')[1]; 6 var credentials = Encoding.UTF8.GetString(Convert.FromBase64String(key)).Split(':'); 7 8 var serverSecret = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:ServerSecret"])); 9 //验证是否是信任用户的用户名和密码,可在数据库中查询 10 if (credentials[0] == "awesome-username" && credentials[1] == "awesome-password") 11 { 12 var result = new 13 { 14 token = GenerateToken(serverSecret) 15 }; 16 17 return Ok(result); 18 } 19 20 return BadRequest(); 21 } 22 23 private string GenerateToken(SecurityKey key) 24 { 25 var now = DateTime.UtcNow; 26 //发行人 27 var issuer = _configuration["JWT:Issuer"]; 28 //接收者?? 29 var audience = _configuration["JWT:Audience"]; 30 var identity = new ClaimsIdentity(); 31 //可以放一些claim进去授权时候使用 32 Claim claim = new Claim(ClaimTypes.Name, "Leo"); 33 identity.AddClaim(claim); 34 //登录凭证 35 var signingCredentials = new SigningCredentials(key, 36 SecurityAlgorithms.HmacSha256); 37 var handler = new JwtSecurityTokenHandler(); 38 //生成token,设置1小时的过期时间 39 var token = handler.CreateJwtSecurityToken(issuer, audience, identity, 40 now, now.Add(TimeSpan.FromHours(1)), now, signingCredentials); 41 var encodedJwt = handler.WriteToken(token); 42 return encodedJwt; 43 }
2.Startup 配置类
1 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) 2 .AddJwtBearer(options => 3 { 4 var serverSecret = new SymmetricSecurityKey(Encoding.UTF8. 5 GetBytes(Configuration["JWT:ServerSecret"])); 6 options.TokenValidationParameters = new 7 TokenValidationParameters 8 { 9 IssuerSigningKey = serverSecret, 10 //RequireExpirationTime = true, 11 ClockSkew = TimeSpan.Zero, 12 ValidIssuer = Configuration["JWT:Issuer"], 13 ValidAudience = Configuration["JWT:Audience"] 14 }; 15 });
3.appsettings.json
"JWT": { "ServerSecret": "qwertyuiopasdfghjklzxcvbnm123456", "Issuer": "https://awesome.io", "Audience": "https://app.awesome.io" },
4.客户端调用
1 static void Main(string[] args) 2 { 3 4 HttpClient client = new HttpClient(); 5 var identity = "awesome-username:awesome-password"; 6 string idString = Base64Code(identity); 7 client.DefaultRequestHeaders.Add("Authorization", $"Basic {idString}"); 8 //var respMsg = client.GetAsync("http://localhost:8082/api/Todo/GetTodoItems"); 9 var respMsg = client.GetAsync("http://localhost:8082/api/Authenticate/GetToken"); 10 string msgBody = respMsg.Result.Content.ReadAsStringAsync().Result; 11 TokenClass obj = JsonConvert.DeserializeObject<TokenClass>(msgBody); 12 string token = obj.token; 13 Console.WriteLine(token); 14 Console.ReadKey(); 15 16 //2.获取token后再次发送请求 17 //var token = "123"; 18 HttpClient getItemsClient = new HttpClient(); 19 getItemsClient.DefaultRequestHeaders.Add("Authorization",$"Bearer {token}"); 20 var respGetItems = getItemsClient.GetAsync("http://localhost:8082/api/Todo/GetTodoItems"); 21 string msgGetItems = respGetItems.Result.Content.ReadAsStringAsync().Result; 22 23 Console.WriteLine(msgGetItems); 24 Console.ReadKey(); 25 26 27 28 }
5.必须在需要验证授权的controller或action上添加 [Authorize]特性才能生效
6.我后期在core2.2遇到了302 问题,找了半天在 stackoverflow 找到答案
1 services.AddAuthentication(options => 2 { 3 options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; 4 options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; 5 }) 6 .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => 7 { 8 var serverSecret = new SymmetricSecurityKey(Encoding.UTF8. 9 GetBytes(Configuration["JWT:ServerSecret"])); 10 options.TokenValidationParameters = new 11 TokenValidationParameters 12 { 13 IssuerSigningKey = serverSecret, 14 //RequireExpirationTime = true, 15 //ClockSkew = TimeSpan.Zero, 16 ValidIssuer = Configuration["JWT:Issuer"], 17 ValidAudience = Configuration["JWT:Audience"] 18 }; 19 20 21 });