准備工作
用VSCode新建webapi項目JwtAuthSample,並打開所在文件夾項目
dotnet new webapi --name JwtAuthSample
編輯JwtAuthSample.csproj,添加watch
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
重新生成一下項目
dotnet restore
然后運行
dotnet watch run
這時候可以用postman來模擬訪問一下webapi
配置Jwt
在ValuesController中添加引用
using Microsoft.AspNetCore.Authorization;
給控制器添加標簽[Authorize]
然后在Startup.cs中的Configure方法中配置使用Authentication
app.UseAuthentication();
添加JwtBearer引用
using Microsoft.AspNetCore.Authentication.JwtBearer;
接下來需要新建一個文件夾Models,在文件夾下面新建一個類JwtSettings.cs
namespace JwtAuthSample { public class JwtSettings { //token是誰頒發的 public string Issuer { get; set; } //token可以給哪些客戶端使用 public string Audience { get; set; } //加密的key public string SecretKey{get;set;} } }
然后需要在appsettings.json中配置jwt參數的值 【注意】 SecretKey必須大於16個,是大於,不是大於等於
{ "Logging": { "IncludeScopes": false, "Debug": { "LogLevel": { "Default": "Warning" } }, "Console": { "LogLevel": { "Default": "Warning" } } }, "JwtSettings":{ "Issuer":"http://localhost:5000", "Audience":"http://localhost:5000", "SecretKey":"Hello-key-----wyt" } }
這時候重新回到Startup.cs的ConfigureServices方法下,將appsettings.json中的文件讀取到JwtSettings中,進行Bind,然后設置jwt參數
添加如下引用
using Microsoft.IdentityModel.Tokens; using System.Text;
ConfigureServices代碼
public void ConfigureServices(IServiceCollection services) { //將appsettings.json中的JwtSettings部分文件讀取到JwtSettings中,這是給其他地方用的 services.Configure<JwtSettings>(Configuration.GetSection("JwtSettings")); //由於初始化的時候我們就需要用,所以使用Bind的方式讀取配置 //將配置綁定到JwtSettings實例中 var jwtSettings=new JwtSettings(); Configuration.Bind("JwtSettings",jwtSettings); services.AddAuthentication(options=>{ //認證middleware配置 options.DefaultAuthenticateScheme=JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme=JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(o=>{ //主要是jwt token參數設置 o.TokenValidationParameters=new Microsoft.IdentityModel.Tokens.TokenValidationParameters{
//Token頒發機構 ValidIssuer =jwtSettings.Issuer,
//頒發給誰 ValidAudience =jwtSettings.Audience, //這里的key要進行加密,需要引用Microsoft.IdentityModel.Tokens IssuerSigningKey=new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey))
//ValidateIssuerSigningKey=true,
////是否驗證Token有效期,使用當前時間與Token的Claims中的NotBefore和Expires對比
//ValidateLifetime=true,
////允許的服務器時間偏移量
//ClockSkew=TimeSpan.Zero
}; }); services.AddMvc(); }
這時再通過postman訪問5000端口,發現狀態碼為401(未授權)
生成 JWT Token
擴展安裝
先安裝幾個重要的擴展
這時候可以在商店中搜索NuGet Package Manager進行安裝,安裝完成后點擊重新加載即可。
如果需要安裝nuget包的話,只要在【查看】-》【命令面板】中輸入NuGet Package Manager,即可進入package安裝,輸入Microsoft.AspNetCore.Authentication.JwtBearer即可進行安裝
這時候查看項目文件發現已經安裝成功
生成jwt token
首先新建一個ViewModel文件夾,並在ViewModel文件夾下面新建LoginViewModel.cs
using System.ComponentModel.DataAnnotations; namespace JwtAuthSample { public class LoginViewModel { //用戶名 [Required] public string User { get; set; } //密碼 [Required] public string Password { get; set; } } }
接下來在Controllers文件夾下新建控制器AuthorizeController.cs,完整代碼如下
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; //引用命名空間 using System.Security.Claims; using Microsoft.IdentityModel.Tokens; using Microsoft.Extensions.Options; using System.Text; using System.IdentityModel.Tokens.Jwt; namespace JwtAuthSample.Controllers { [Route("api/[controller]")] public class AuthorizeController : Controller { private JwtSettings _jwtSettings; public AuthorizeController(IOptions<JwtSettings> _jwtSettingsAccesser) { _jwtSettings=_jwtSettingsAccesser.Value; } [HttpPost] public IActionResult Token([FromBody]LoginViewModel viewModel) { if(ModelState.IsValid)//判斷是否合法 { if(!(viewModel.User=="wyt"&&viewModel.Password=="123456"))//判斷賬號密碼是否正確 { return BadRequest(); } var claim=new Claim[]{ new Claim(ClaimTypes.Name,"wyt"), new Claim(ClaimTypes.Role,"admin") }; //對稱秘鑰 var key=new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey)); //簽名證書(秘鑰,加密算法) var creds=new SigningCredentials(key,SecurityAlgorithms.HmacSha256); //生成token [注意]需要nuget添加Microsoft.AspNetCore.Authentication.JwtBearer包,並引用System.IdentityModel.Tokens.Jwt命名空間 var token=new JwtSecurityToken(_jwtSettings.Issuer,_jwtSettings.Audience,claim,DateTime.Now,DateTime.Now.AddMinutes(30),creds); return Ok(new {token=new JwtSecurityTokenHandler().WriteToken(token)}); } return BadRequest(); } } }
這時候用postman進行請求
此時訪問http://localhost:5000/api/values端口發現401無法訪問
這時候加上token進行訪問,訪問成功
token校驗
可以把生成的token放在官方網站上進行校驗
官方網址:https://jwt.io/
這時候把的json粘貼進去會發現部分信息已經解析出來了,而由於secret只有自己填進去才能校驗成功,否則校驗失敗。
這時我們填進去正確的secretkey:Hello-key-----wyt 校驗成功