zoukankan      html  css  js  c++  java
  • WebApi使用JWT认证(二)

    这是第二部:实现NetCore上的WebApi使用JWT认证

    1、NetCore新建一个WebApi的项目

    2、打开AppSettings.json,添加Jwt的信息,这里为了演示而已

    {
      "Logging": {
        "IncludeScopes": false,
        "Debug": {
          "LogLevel": {
            "Default": "Warning"
          }
        },
        "Console": {
          "LogLevel": {
            "Default": "Warning"
          }
        }
      },
      "JwtSettings": {
        "Issuer": "XXX",
        "Audience": "XXXX",
        "SecretKey": "To live is to change the world!"
      }
    }

    3、Models下新建两个类,一个用于登录,一个用于获取配置文件中的值

    1 namespace NerCoreJwt.Models
    2 {
    3     public class LoginViewModel
    4     {
    5         public string UserName { get; set; } = "wangshibang";
    6 
    7         public string Password { get; set; } = "123456";
    8     }
    9 }
     1 namespace NerCoreJwt.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 
    21 }

    4、新建一个Controller,用来写登录后生成Token逻辑

     1 using Microsoft.AspNetCore.Mvc;
     2 using Microsoft.Extensions.Options;
     3 using Microsoft.IdentityModel.Tokens;
     4 using NerCoreJwt.Models;
     5 using System;
     6 using System.IdentityModel.Tokens.Jwt;
     7 using System.Security.Claims;
     8 using System.Text;
     9 
    10 namespace NerCoreJwt.Controllers
    11 {
    12     [Route("api/[controller]/[action]")]
    13     public class AuthorizeController : Controller
    14     {
    15         private JwtSettings setting;
    16         public AuthorizeController(IOptions<JwtSettings> options)
    17         {
    18             setting = options.Value;
    19         }
    20 
    21         [HttpPost]
    22         public IActionResult Login(LoginViewModel login)
    23         {
    24             if (ModelState.IsValid)
    25             {
    26                 if (login.UserName == "wangshibang" && login.Password == "123456")
    27                 {
    28                     var claims = new Claim[] {
    29                         new Claim(ClaimTypes.Name, login.UserName),
    30                         new Claim(ClaimTypes.Role, "admin, Manage")
    31                     };
    32                     var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(setting.SecretKey));
    33                     var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
    34                     var token = new JwtSecurityToken(
    35                         setting.Issuer,
    36                         setting.Audience,
    37                         claims,
    38                         DateTime.Now,
    39                         DateTime.Now.AddMinutes(30),
    40                         creds);
    41                     return Ok(new { Token = new JwtSecurityTokenHandler().WriteToken(token) });
    42                 }
    43             }
    44             return BadRequest();
    45         }
    46 
    47         [HttpGet]
    48         public IActionResult NoValidate()
    49         {
    50             return Ok();
    51         }
    52     }
    53 }

    5、StartUp类里面添加从Configure<JwtSettings>中获取Section才可以使用IOptions获取里面的内容,为了省事就全部贴出来了

     1 using Microsoft.AspNetCore.Authentication.JwtBearer;
     2 using Microsoft.AspNetCore.Builder;
     3 using Microsoft.AspNetCore.Hosting;
     4 using Microsoft.Extensions.Configuration;
     5 using Microsoft.Extensions.DependencyInjection;
     6 using NerCoreJwt.Models;
     7 using System.Linq;
     8 using System.Threading.Tasks;
     9 
    10 namespace NerCoreJwt
    11 {
    12     public class Startup
    13     {
    14         public Startup(IConfiguration configuration)
    15         {
    16             Configuration = configuration;
    17         }
    18 
    19         public IConfiguration Configuration { get; }
    20 
    21         // This method gets called by the runtime. Use this method to add services to the container.
    22         public void ConfigureServices(IServiceCollection services)
    23         {
    24             services.Configure<JwtSettings>(Configuration.GetSection("JwtSettings"));
    25             JwtSettings setting = new JwtSettings();
    26             Configuration.Bind("JwtSettings", setting);
    27             services.AddAuthentication(option =>
    28             {
    29                 option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    30                 option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    31             }).AddJwtBearer(config =>
    32             {
    33                 /*
    34                 config.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
    35                 {
    36                     ValidAudience = setting.Audience,
    37                     ValidIssuer = setting.Issuer,
    38                     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(setting.SecretKey))
    39                 };
    40                 */
    41                 config.SecurityTokenValidators.Clear();
    42                 config.SecurityTokenValidators.Add(new MyTokenValidate());
    43                 config.Events = new JwtBearerEvents()
    44                 {
    45                     OnMessageReceived = context =>
    46                     {
    47                         var token = context.Request.Headers["myToken"];
    48                         context.Token = token.FirstOrDefault();
    49                         return Task.CompletedTask;
    50                     }
    51                     
    52                 };
    53             });
    54 
    55             services.AddMvc();
    56         }
    57 
    58         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    59         public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    60         {
    61             if (env.IsDevelopment())
    62             {
    63                 app.UseDeveloperExceptionPage();
    64             }
    65             app.UseAuthentication();
    66             app.UseMvc();
    67         }
    68     }
    69 }

    6、Token生成了,可以用PostMan调用接口试试,把生成的Token粘到jwt.io官网看看里面的信息

    下面我们来进行授权

    7、为了自定义授权方法,我们需要新建一个类,继承自ISecurityTokenValidator接口

     1 using Microsoft.AspNetCore.Authentication.JwtBearer;
     2 using Microsoft.IdentityModel.Tokens;
     3 using System.IdentityModel.Tokens.Jwt;
     4 using System.Linq;
     5 using System.Security.Claims;
     6 
     7 namespace NerCoreJwt
     8 {
     9     public class MyTokenValidate : ISecurityTokenValidator
    10     {
    11         public bool CanValidateToken => true;
    12 
    13         public int MaximumTokenSizeInBytes { get ; set ; }
    14 
    15         public bool CanReadToken(string securityToken)
    16         {
    17             return true;
    18         }
    19 
    20         public ClaimsPrincipal ValidateToken(string securityToken, TokenValidationParameters validationParameters, out SecurityToken validatedToken)
    21         {
    22             ClaimsPrincipal principal;
    23             try
    24             {
    25                 validatedToken = null;
    26                 //这里需要验证生成的Token
    27                 /*
    28 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoid2FuZ3NoaWJhbmciLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJhZG1pbiwgTWFuYWdlIiwibmJmIjoxNTIyOTI0MDgxLCJleHAiOjE1MjI5MjU4ODEsImlzcyI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTAwMCIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NTAwMCJ9.fa0jDYt_MqHFcwQfsMS30eCsjEwQt_uiv96bGtMQJBE
    29                 */
    30                 var token = new JwtSecurityToken(securityToken);
    31                 //获取到Token的一切信息
    32                 var payload = token.Payload;
    33                 var role = (from t in payload where t.Key == ClaimTypes.Role select t.Value).FirstOrDefault();
    34                 var name = (from t in payload where t.Key == ClaimTypes.Name select t.Value).FirstOrDefault();
    35                 var issuer = token.Issuer;
    36                 var key = token.SecurityKey;
    37                 var audience = token.Audiences;
    38                 var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
    39                 identity.AddClaim(new Claim(ClaimTypes.Name, name.ToString()));
    40                 identity.AddClaim(new Claim(ClaimsIdentity.DefaultRoleClaimType, "admin"));
    41                 principal = new ClaimsPrincipal(identity);
    42             }
    43             catch
    44             {
    45                 validatedToken = null;48                 principal = null;
    49             }
    50             return principal;
    51         }
    52     }
    53 }

    8、然后注释掉上面代码我注册的部分,因为这是原生的Authorize验证特性,添加后面的自定义验证逻辑

    9、在接口上面添加Authorize特性,用PostMan调用接口传入生成的Token,设置断点看看效果吧

     1 using Microsoft.AspNetCore.Authorization;
     2 using Microsoft.AspNetCore.Mvc;
     3 using System.Collections.Generic;
     4 
     5 namespace NerCoreJwt.Controllers
     6 {
     7     [Route("api/[controller]")]
     8     public class ValuesController : Controller
     9     {
    10         // GET api/values
    11         [Authorize(Roles = "admin")]
    12         [HttpGet]
    13         public IEnumerable<string> Get()
    14         {
    15             return new string[] { "value1", "value2" };
    16         }
    17 
    18         // GET api/values/5
    19         [HttpGet("{id}")]
    20         public string Get(int id)
    21         {
    22             return "value";
    23         }
    24 
    25         // POST api/values
    26         [HttpPost]
    27         public void Post([FromBody]string value)
    28         {
    29         }
    30 
    31         // PUT api/values/5
    32         [HttpPut("{id}")]
    33         public void Put(int id, [FromBody]string value)
    34         {
    35         }
    36 
    37         // DELETE api/values/5
    38         [HttpDelete("{id}")]
    39         public void Delete(int id)
    40         {
    41         }
    42     }
    43 }
  • 相关阅读:
    【CUDA开发】 Check failed: error == cudaSuccess (8 vs. 0) invalid device function
    【CUDA开发】 Check failed: error == cudaSuccess (8 vs. 0) invalid device function
    【神经网络与深度学习】【CUDA开发】服务器(多GPU)caffe安装和编译
    【神经网络与深度学习】【CUDA开发】服务器(多GPU)caffe安装和编译
    【神经网络与深度学习】Win10+VS2015 caffe环境搭建(极其详细)
    【神经网络与深度学习】Win10+VS2015 caffe环境搭建(极其详细)
    【OpenCV开发】OpenCV3后IPLimage转换成MAT的问题
    【OpenCV开发】OpenCV3后IPLimage转换成MAT的问题
    【VS开发】【视频开发】利用ffmpeg+opencv实现画中画
    【VS开发】【视频开发】利用ffmpeg+opencv实现画中画
  • 原文地址:https://www.cnblogs.com/wangyulong/p/8734495.html
Copyright © 2011-2022 走看看