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 }
    View Code

    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
    View Code

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

    1 app.UseAuthentication();
    View Code

    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 }
    View Code

    这样调用这个方法就会生成一个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 }
    View Code

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

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

    他返回了Http200就是成功了

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

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

  • 相关阅读:
    eclipse如何与git 配合工作。
    git托管代码(二)
    PPC2003 安装 CFNET 3.5成功
    我的Window Mobile WCF 項目 第三篇 WM窗体设计
    我的Window Mobile WCF 項目 第一篇Mobile开发和WinForm开发的区别
    我的Window Mobile WCF 項目 第七天
    我的Window Mobile WCF 項目 第二篇 WindowsMobile访问WCF
    WCF 用vs2010 和 vs2008的简单对比测试
    vs2010beta1 和 搜狗输入法 冲突,按下 Ctrl 键就报错,重装搜狗解决
    我的Window Mobile WCF 項目 第六天 (二)
  • 原文地址:https://www.cnblogs.com/wangyulong/p/8962180.html
Copyright © 2011-2022 走看看