NetCore+Dapper WebApi架構搭建(六):添加JWT認證

WebApi必須保證安全,如今來添加JWT認證git

一、打開appsettings.json添加JWT認證的配置信息github

二、在項目根目錄下新建一個Models文件夾,添加一個JwtSettings.cs的實體json

 1 namespace Dinner.WebApi.Models
 2 {
 3     public class JwtSettings
 4     {
 5         /// <summary>
 6         /// 證書頒發者
 7         /// </summary>
 8         public string Issuer { get; set; }
 9 
10         /// <summary>
11         /// 容許使用的角色
12         /// </summary>
13         public string Audience { get; set; }
14 
15         /// <summary>
16         /// 加密字符串
17         /// </summary>
18         public string SecretKey { get; set; }
19     }
20 }
View Code

三、Startup.cs文件中的ConfigureServices添加Jwt認證的代碼api

 1 #region JWT認證
 2 
 3             services.Configure<JwtSettings>(Configuration.GetSection("JwtSettings"));
 4             JwtSettings setting = new JwtSettings();
 5             //綁定配置文件信息到實體
 6             Configuration.Bind("JwtSettings", setting);
 7             //添加Jwt認證
 8             services.AddAuthentication(option =>
 9             {
10                 option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
11                 option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
12             }).AddJwtBearer(config =>
13             {
14                 config.TokenValidationParameters = new TokenValidationParameters
15                 {
16                     ValidAudience = setting.Audience,
17                     ValidIssuer = setting.Issuer,
18                     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(setting.SecretKey))
19                 };
20                 /*
21                 config.SecurityTokenValidators.Clear();
22                 config.SecurityTokenValidators.Add(new MyTokenValidate());
23                 config.Events = new JwtBearerEvents()
24                 {
25                     OnMessageReceived = context =>
26                     {
27                         var token = context.Request.Headers["myToken"];
28                         context.Token = token.FirstOrDefault();
29                         return Task.CompletedTask;
30                     }
31                 };
32                 */
33             });
34 
35             #endregion
View Code

四、Startup.cs文件中的Configure添加Jwt認證的代碼安全

1 app.UseAuthentication();
View Code

五、基本配置都弄完了,如今是生成JwtToken,在ValuesController中添加一個生成Jwt的Actionapp

 1 using Dinner.WebApi.Models;
 2 using Microsoft.AspNetCore.Mvc;
 3 using Microsoft.Extensions.Options;
 4 using Microsoft.IdentityModel.Tokens;
 5 using System;
 6 using System.Collections.Generic;
 7 using System.IdentityModel.Tokens.Jwt;
 8 using System.Security.Claims;
 9 using System.Text;
10 
11 namespace Dinner.WebApi.Controllers
12 {
13     [Route("api/[controller]/[action]")]
14     public class ValuesController : Controller
15     {
16         private readonly JwtSettings setting;
17         public ValuesController(IOptions<JwtSettings> _setting)
18         {
19             setting = _setting.Value;
20         }
21         // GET api/values
22         [HttpGet]
23         public IEnumerable<string> Get()
24         {
25             return new string[] { "value1", "value2" };
26         }
27 
28         // GET api/values/5
29         [HttpGet("{id}")]
30         public string Get(int id)
31         {
32             return "value";
33         }
34 
35         // POST api/values
36         [HttpPost]
37         public void Post([FromBody]string value)
38         {
39         }
40 
41         // PUT api/values/5
42         [HttpPut("{id}")]
43         public void Put(int id, [FromBody]string value)
44         {
45         }
46 
47         // DELETE api/values/5
48         [HttpDelete("{id}")]
49         public void Delete(int id)
50         {
51         }
52 
53         [HttpGet]
54         public IActionResult GetGenerateJWT()
55         {
56             try
57             {
58                 var claims = new Claim[] 
59                 {
60                     new Claim(ClaimTypes.Name, "wangshibang"),
61                     new Claim(ClaimTypes.Role, "admin, Manage")
62                 };
63                 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(setting.SecretKey));
64                 var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
65                 var token = new JwtSecurityToken(
66                     setting.Issuer,
67                     setting.Audience,
68                     claims,
69                     DateTime.Now,
70                     DateTime.Now.AddMinutes(30),
71                     creds);
72                 return Ok(new { Token = new JwtSecurityTokenHandler().WriteToken(token) });
73             }
74             catch (Exception ex)
75             {
76                 return BadRequest(ex.Message);
77             }   
78             
79         }
80     }
81 }
View Code

這樣調用這個方法就會生成一個JwtToken,而後在UsersController上面添加一個[Authorize]的特性框架

上一篇咱們說過SwaggerUI配置的最後一句有一個options.OperationFilter<HttpHeaderOperation>(); 這裏咱們來看這個HttpHeaderOperationide

 1 using Microsoft.AspNetCore.Authorization;
 2 using Swashbuckle.AspNetCore.Swagger;
 3 using Swashbuckle.AspNetCore.SwaggerGen;
 4 using System.Collections.Generic;
 5 using System.Linq;
 6 
 7 namespace Dinner.WebApi
 8 {
 9     public class HttpHeaderOperation : IOperationFilter
10     {
11         public void Apply(Operation operation, OperationFilterContext context)
12         {
13             if (operation.Parameters == null)
14             {
15                 operation.Parameters = new List<IParameter>();
16             }
17 
18             var actionAttrs = context.ApiDescription.ActionAttributes();
19 
20             var isAuthorized = actionAttrs.Any(a => a.GetType() == typeof(AuthorizeAttribute));
21 
22             if (isAuthorized == false) //提供action都沒有權限特性標記,檢查控制器有沒有
23             {
24                 var controllerAttrs = context.ApiDescription.ControllerAttributes();
25 
26                 isAuthorized = controllerAttrs.Any(a => a.GetType() == typeof(AuthorizeAttribute));
27             }
28 
29             var isAllowAnonymous = actionAttrs.Any(a => a.GetType() == typeof(AllowAnonymousAttribute));
30 
31             if (isAuthorized && isAllowAnonymous == false)
32             {
33                 operation.Parameters.Add(new NonBodyParameter()
34                 {
35                     Name = "Authorization",  //添加Authorization頭部參數
36                     In = "header",
37                     Type = "string",
38                     Required = false
39                 });
40             }
41         }
42     }
43 }
View Code

這個代碼主要就是在swagger頁面添加了一個Authorization的頭部輸入框信息,以便來進行驗證測試

如今咱們基本工做都作好了,打開頁面測試吧,注意:傳入的Authorization參數必須是Bearer xxxxxxx的形式(xxxxxxx爲生成的Token)ui

他返回了Http200就是成功了

整個項目的框架基本算是搭建好了,這只是一個雛形而已,其實Authorize這一塊須要建一個BaseController繼承Controller再在BaseController上添加一個Authorize而後全部Controller繼承BaseController就不用一個一個的寫Authorize了,不須要驗證的加個AllowAnonymous就能夠了,其餘的直接擴展倉儲接口寫倉儲就能夠直接調用了

源碼地址: https://github.com/wangyulong0505/Dinner

相關文章
相關標籤/搜索