本章讲下关于JWT身份验证的实现
项目的基础搭建参见:https://blog.csdn.net/liwan09/article/details/100733455
Autofac的注册实现参见:https://blog.csdn.net/liwan09/article/details/100734233
JWT身份验证的实现
NetCore.Repository 项目中的Common添加JWTSettings类
using System;
using System.Collections.Generic;
using System.Text;
namespace NetCore.Repository.Common
{
/// <summary>
/// JWT验证配置信息
/// </summary>
public class JWTSettings
{
/// <summary>
/// token颁发者
/// </summary>
public string Issuer { get; set; }
/// <summary>
/// token使用者
/// </summary>
public string Audience { get; set; }
/// <summary>
/// token加密的key
/// </summary>
public string SecretKey { get; set; }
}
}
NetCore.WebApi项目中,在appsettings中配置JWT验证秘钥等信息
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"NetCoreDBContext": "Data Source=.;Initial Catalog=NetCoreWebApi;User=sa;Password=123456"
},
"JWTSettings": {
"Issuer": "http://localhost:5000", //token颁发者
"Audience": "http://localhost:5000", //token使用者
"SecretKey": "Hello-key-----wyt" //token加密的key
}
}
NetCore.WebApi项目中Startup.cs中的ConfigureServices中添加JWT身份验证
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
#region "JWT身份验证"
//从appsettings.json获取JWT验证配置信息
services.Configure<JWTSettings>(Configuration.GetSection("JWTSettings"));
// assign JwtSettings model
var jwtSettings = new JWTSettings();
Configuration.Bind("JWTSettings", jwtSettings);
//添加授权信息
services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(o => {
// set jwt token parameters
o.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = jwtSettings.Issuer,//Issuer
ValidAudience = jwtSettings.Audience,//Audience
//Encryption secret key
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey)),
ValidateIssuer = true, //whether or not valid Issuer
ValidateAudience = true, //whether or not valid Audience
ValidateLifetime = true, //whether or not valid out-of-service time
ValidateIssuerSigningKey = true, //whether or not valid SecurityKey
ClockSkew = TimeSpan.Zero//Allowed server time offset
};
});
#endregion
services.AddDbContext<NetCoreDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("NetCoreDBContext")));//获取数据库连接
return new AutofacServiceProvider(AutoFacApp.InitAutoFac(services));
}
在Configure 中添加app.UseAuthentication();//启用身份验证代码
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseAuthentication();//启用身份验证
app.UseHttpsRedirection();
app.UseMvc();
}
NetCore.WebApi项目中添加LoginController,用于生成JWT口令,实现登录
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System.Text;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using NetCore.App;
using NetCore.Repository;
using NetCore.Repository.Common;
using NetCore.Repository.RequestEntity;
namespace NetCore.WebApi.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class LoginController : ControllerBase
{
private readonly UserInfoApp userInfoApp;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="_userInfoApp"></param>
public LoginController(UserInfoApp _userInfoApp)
{
userInfoApp = _userInfoApp;
}
/// <summary>
/// 登录
/// </summary>
/// <param name="loginRequest">登录信息</param>
/// <returns></returns>
[HttpPost]
public ResponseResult Login(LoginRequest loginRequest)
{
var userInfo = userInfoApp.Login(loginRequest.UserName, loginRequest.PassWord);
if (userInfo == null)
{
return new ResponseResult() { Code = 201, Message = "用户名或密码错误!" };
}
else
{
string strToken = "";
var claim = new Claim[]{
new Claim(ClaimTypes.Name,userInfo.LoginAccount),
//new Claim(ClaimTypes.Role,userInfo.RoleID),
new Claim("UserTrueName",userInfo.UserName),
new Claim("UserID",userInfo.ID)
};
var jwtSettings = AutoFacApp.GetFromFac<IOptions<JWTSettings>>();
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.Value.SecretKey)); //对称秘钥
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);//签名证书(秘钥,加密算法)
//生成token [注意]需要nuget添加Microsoft.AspNetCore.Authentication.JwtBearer包,并引用System.IdentityModel.Tokens.Jwt命名空间
var token = new JwtSecurityToken
(
issuer: jwtSettings.Value.Issuer,
audience: jwtSettings.Value.Audience,
claims: claim,
notBefore: DateTime.Now,
expires: DateTime.Now.AddHours(2),//过期时间
signingCredentials: creds
);
strToken = new JwtSecurityTokenHandler().WriteToken(token);//生成口令
return new ResponseResult() { Message = "登陆成功!", Data = strToken };
}
}
}
}
通过PostMan调用此接口获取登录口令
在UserInfoController 中添加 [Authorize] 身份验证
[Route("api/[controller]/[action]")]
[ApiController]
[Authorize]
public class UserInfoController : ControllerBase
再次调取用户信息接口,如果没有口令或者口令不正确,将返回401代码
完整代码下载地址:https://download.csdn.net/download/liwan09/11717224