.net core3.1中實現簡單的jwt認證
阿新 • • 發佈:2020-09-07
1.建立專案
使用visual studio建立一個名為JwtDemo的空專案,建立後如圖
2.新增依賴項
- 在nuget包管理器中搜索 Microsoft.AspNetCore.Authentication.JwtBearer、System.IdentityModel.Tokens.Jwt
- 在nuget包管理控制檯安裝
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -Version 3.1.7 Install-Package System.IdentityModel.Tokens.Jwt -Version 6.7.1
3.編寫程式碼
建立一個介面(IJwtAuthenticationHandler),宣告一個用於建立token的方法(Authenticate)
namespace JwtDemo
{
public interface IJwtAuthenticationHandler
{
string Authenticate(string username, string password);
}
}
建立一個類,繼承介面(IJwtAuthenticationHandler),並實現方法,這裡簡單起見就將使用者硬編碼在程式碼中
using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; using System.Text; using Microsoft.IdentityModel.Tokens; namespace JwtDemo { public class JwtAuthenticationHandler: IJwtAuthenticationHandler { private readonly IDictionary<string, string> users = new Dictionary<string, string>() { {"user1","password1"}, {"user2","password2"}, }; private readonly string _token; //宣告一個加密的金鑰,由外部傳入 public JwtAuthenticationHandler(string token) { _token = token; } public string Authenticate(string username, string password) { //如果使用者名稱密碼錯誤則返回null if (!users.Any(t => t.Key == username && t.Value == password)) { return null; } var tokenKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_token)); var tokenHandler = new JwtSecurityTokenHandler(); var tokenDescriptor = new SecurityTokenDescriptor() { SigningCredentials = new SigningCredentials(tokenKey, SecurityAlgorithms.HmacSha256), Expires = DateTime.Now.AddMinutes(10), Subject = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name,username), }) }; var token = tokenHandler.CreateJwtSecurityToken(tokenDescriptor); return tokenHandler.WriteToken(token); } } }
修改Startup類
using System.Text; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.IdentityModel.Tokens; namespace JwtDemo { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddControllers(); string tokenSecretKey = "this is a test token secret key"; //加密的金鑰 services.AddAuthentication(config => { //認證方案設定為Jwt config.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; config.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(config=> { config.RequireHttpsMetadata = false; config.SaveToken = true; //儲存token config.TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = false,//不驗證簽發人 ValidateAudience = false, //不驗證聽眾 ValidateIssuerSigningKey = true, //驗證簽發者金鑰 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenSecretKey)) //簽發者金鑰 }; }); //將生成token的類註冊為單例 services.AddSingleton<IJwtAuthenticationHandler>(new JwtAuthenticationHandler(tokenSecretKey)); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
建立一個控制器(UserController),包含一個認證方法和一個獲取使用者列表(加了許可權認證)的方法
using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace JwtDemo.Controllers
{
[ApiController]
public class UserController: Controller
{
private readonly IJwtAuthenticationHandler _jwtAuthenticationHandler;
//建構函式注入生成token的類
public UserController(IJwtAuthenticationHandler jwtAuthenticationHandler)
{
_jwtAuthenticationHandler = jwtAuthenticationHandler;
}
[AllowAnonymous] //表示可以匿名訪問
[Route("user/authenticate")]
[HttpPost]
public IActionResult Authenticate([FromBody] LoginViewModel loginViewModel)
{
var token = _jwtAuthenticationHandler.Authenticate(loginViewModel.UserName,loginViewModel.Password);
if (token == null)
{
return Unauthorized();
}
return Ok(token);
}
[Authorize] //表示需要認證授權訪問
[Route("user/list")]
[HttpGet]
public List<object> List()
{
return new List<object>()
{
"user1","user2","user3","user..."
};
}
}
}
LoginViewModel類
namespace JwtDemo.Controllers
{
public class LoginViewModel
{
public string UserName { get; set; }
public string Password { get; set; }
}
}