.net core3.1中實現簡單的jwt認證
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; }
}
}