zoukankan      html  css  js  c++  java
  • NetCore+Dapper WebApi架构搭建(六):添加JWT认证

    WebApi必须保证安全,现在来添加JWT认证

    1、打开appsettings.json添加JWT认证的配置信息

    2、在项目根目录下新建一个Models文件夹,添加一个JwtSettings.cs的实体

     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 }

    3、Startup.cs文件中的ConfigureServices添加Jwt认证的代码

     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

    4、Startup.cs文件中的Configure添加Jwt认证的代码

     1 app.UseAuthentication(); 

    5、基本配置都弄完了,现在是生成JwtToken,在ValuesController中添加一个生成Jwt的Action

     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 }

    这样调用这个方法就会生成一个JwtToken,然后在UsersController上面添加一个[Authorize]的特性

    上一篇我们说过SwaggerUI配置的最后一句有一个options.OperationFilter<HttpHeaderOperation>(); 这里我们来看这个HttpHeaderOperation

     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 }

    这个代码主要就是在swagger页面添加了一个Authorization的头部输入框信息,以便来进行验证

    现在我们基本工作都做好了,打开页面测试吧,注意:传入的Authorization参数必须是Bearer xxxxxxx的形式(xxxxxxx为生成的Token)

    他返回了Http200就是成功了

    整个项目的框架基本算是搭建好了,这只是一个雏形而已,其实Authorize这一块需要建一个BaseController继承Controller再在BaseController上添加一个Authorize然后所有Controller继承BaseController就不用一个一个的写Authorize了,不需要验证的加个AllowAnonymous就可以了,其他的直接扩展仓储接口写仓储就可以直接调用了

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

    来源:cnblogs.com/wangyulong/p/8962180.html

  • 相关阅读:
    sql server登录账户看不到sql server代理和维护计划
    Redis(1.19)redis内存消耗、redis内存优化
    【最佳实践】bat实现自动化运行sql
    Redis(1.18)redis阻塞分析
    某机场网络环境分析
    【js】setInterval是个坑!chrome定时截图保存实现
    【操作系统】CPU中的时间片的概念
    Jeff Atwood:软件工程已死?
    vscode配置 eslint+prettierrc自动格式化vue3、ts、tsx文件
    基于.NET的大型Web站点StackOverflow架构分析
  • 原文地址:https://www.cnblogs.com/frank0812/p/12864622.html
Copyright © 2011-2022 走看看