JwtBearer认证是一种标准的,通用的,无状态的,与语言无关的认证方式。Bearer验证属于HTTP协议标准验证。
如果不希望api被所有人调用,就要 控制 api 的访问权限,只有通过认证的用户,才允许调用api。
Bearer Token(Token 令牌)
为了验证使用者的身份,需要客户端向服务器端提供一个可靠的验证信息,称为Token,这个token通常由Json数据格式组成,通过hash散列算法生成一个字符串,所以称为Json Web Token(Json表示令牌的原始值是一个Json格式的数据,web表示是在互联网传播的,token表示令牌,简称JWT)。
JWT
一个JWT:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiQW5nZWxhRGFkZHkiLCJleHAiOjE1MzMwOTAxMjQsImlzcyI6Imp3dHRlc3QiLCJhdWQiOiJqd3R0ZXN0In0.JAw0Jdg9Z_bFXm8Chsw5ZFfhKDk9lV-g-TkqN7cUcf8"
}
JWT是由 . 分割的三部分组成:
头部(Header)
载荷(Payload) : 这一部分是JWT主要的信息存储部分,其中包含了许多种的声明(claims)。
签名(Signature):使用保存在服务端的秘钥对其签名,用来验证发送者的JWT的同时也能确保在期间不被篡改。
生成jwt token
在一个Controller的方法中生成 jwt token ,一般在用户登陆 验证方法中,如果用户登陆验证成功 , 就 返回一个 token 。
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
namespace JWTTest.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly IConfiguration _configuration;
public ValuesController(IConfiguration configuration)
{
_configuration = configuration;
}
// GET api/values
[HttpGet]
//[Authorize]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
// POST api/values
[HttpPost]
public IActionResult Post(string username, string password)
{
if (username == "AngelaDaddy" && password == "123456")
{
// push the user’s name into a claim, so we can identify the user later on.
var claims = new[]
{
new Claim(ClaimTypes.Name, username)
};
//sign the token using a secret key.This secret will be shared between your API and anything that needs to check that the token is legit.
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SecurityKey"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
//.NET Core’s JwtSecurityToken class takes on the heavy lifting and actually creates the token.
/**
* Claims (Payload)
Claims 部分包含了一些跟这个 token 有关的重要信息。 JWT 标准规定了一些字段,下面节选一些字段:
iss: The issuer of the token,token 是给谁的 发送者
audience: 接收的
sub: The subject of the token,token 主题
exp: Expiration Time。 token 过期时间,Unix 时间戳格式
iat: Issued At。 token 创建时间, Unix 时间戳格式
jti: JWT ID。针对当前 token 的唯一标识
除了规定的字段外,可以包含其他任何 JSON 兼容的字段。
* */
var token = new JwtSecurityToken(
issuer: "jwttest",
audience: "jwttest",
claims: claims,
expires: DateTime.Now.AddMinutes(30),
signingCredentials: creds);
return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(token)
});
}
return BadRequest("用户名密码错误");
}
}
}
在appsettings.json中:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"SecurityKey": "dd%88*377f6d&f£$$£$FdddFF33fssDG^!3"
}
测试生成token :
1.jpg
使用jwt验证
在Startup.cs中配置 服务 ,添加jwt 验证 服务:
using System.Text;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
namespace JWTTest
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//添加jwt验证:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => {
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,//是否验证Issuer
ValidateAudience = true,//是否验证Audience
ValidateLifetime = true,//是否验证失效时间
ValidateIssuerSigningKey = true,//是否验证SecurityKey
ValidAudience = "jwttest",//Audience
ValidIssuer = "jwttest",//Issuer,这两项和前面签发jwt的设置一致
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SecurityKey"]))//拿到SecurityKey
};
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseAuthentication();//启用验证
app.UseHttpsRedirection();
app.UseMvc();
}
}
}
测试
新建一个Conroller , 在需要验证的地方加上 [Authorize] :
using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace JWTTest.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
// GET api/values
[HttpGet]
[Authorize]//添加Authorize标签,可以加在方法上,也可以加在类上
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
}
}
- get请求 : api/test 发生错误,无法通过验证
- post 请求 : api/test/1 返回 " value "
-
post请求 : api/values?username=AngelaDaddy&password=123456 返回{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiQW5nZWxhRGFkZHkiLCJleHAiOjE1MzMwOTAxMjQsImlzcyI6Imp3dHRlc3QiLCJhdWQiOiJqd3R0ZXN0In0.JAw0Jdg9Z_bFXm8Chsw5ZFfhKDk9lV-g-TkqN7cUcf8"
}
4.发送get请求的时候,在header中带上 token ,请求 api/test , 通过验证,请求成功,返回 ["value1","value2"]
2.jpg
参考 :
https://www.cnblogs.com/RainingNight/p/jwtbearer-authentication-in-asp-net-core.html
https://www.jianshu.com/p/294ea94f0087?utm_source=oschina-app
网友评论