目录
AspNet Core: Jwt身份认证
资源服务器
创建项目
新建一个“AspNetCore WebApi” 项目,名为:DotNet.WebApi.Jwt.ApiResources
依赖包
添加依赖包:
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.3" />
添加API
新建控制器 Controllers/StudentController.cs:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace DotNet.WebApi.Jwt.ApiResources.Controllers
{
//[Authorize(Policy = "OnlyRead")]
[Authorize]
[Route("api/[controller]")]
[ApiController]
public class StudentController : ControllerBase
{
[Authorize(Policy = "ReadWrite")]
[HttpGet("GetStudents")]
public ActionResult<dynamic> GetStudents()
{
return new List<dynamic>()
{
new {Id=1,Name="张三",Age=21 },
new {Id=2,Name="李四",Age=22 },
new {Id=3,Name="王五",Age=23 },
};
}
[Authorize(Policy = "OnlyRead")]
[HttpGet("GetStudent")]
public ActionResult<dynamic> GetStudent()
{
return new List<dynamic>()
{
new { Id = 10, Name = "钱六", Age = 19 }
};
}
}
}
Program
将 Program.cs 修改为:
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
namespace DotNet.WebApi.Jwt.ApiResources
{
public class Program
{
public static void Main(string[] args)
{
Console.Title = "API资源服务器";
var builder = WebApplication.CreateBuilder(args);
//设置跨域
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
//允许任何来源访问。
builder.AllowAnyOrigin().AllowAnyHeader();
//将isexpired头添加到策略中。
builder.WithExposedHeaders(new string[] { "isexpired" });
});
});
//配置策略授权
builder.Services.AddAuthorization(options => {
options.AddPolicy("OnlyRead", policy => policy.RequireRole("Read").Build());
});
//配置JWT。
builder.Services.AddAuthentication(a =>
{
a.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
a.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(j =>
{
j.RequireHttpsMetadata = false;
j.SaveToken = true;
j.TokenValidationParameters = new TokenValidationParameters
{
//是否调用对签名securityToken的SecurityKey进行验证
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("798654167464654646")),//签名秘钥
ValidateIssuer = true,//是否验证颁发者
ValidIssuer = "dotnet-jwt",//颁发者
ValidateAudience = true, //是否验证接收者
ValidAudience = "StudentAPI",//接收者
ValidateLifetime = true,//是否验证失效时间
};
//捕获Token过期事件
j.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
//出现此类异常。
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
//在响应头中添加isexpired:true键值对。
context.Response.Headers.Add("isexpired", "true");
}
return Task.CompletedTask;
}
};
});
builder.Services.AddAuthorization();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
if (app.Environment.IsProduction())
{
//生产环境端口号
app.Urls.Add("https://*:6002");
}
app.UseHttpsRedirection();
app.UseCors(); //启用跨域
app.UseAuthentication(); //身份验证
app.UseAuthorization(); //授权
app.MapControllers();
app.Run();
}
}
}
代码解析:
(1)添加JWT 身份认证中间件
//配置JWT。
builder.Services.AddAuthentication(a =>
{
a.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
a.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(j =>
{
j.RequireHttpsMetadata = false;
j.SaveToken = true;
j.TokenValidationParameters = new TokenValidationParameters
{
//是否调用对签名securityToken的SecurityKey进行验证
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("798654167464654646")),//签名秘钥
ValidateIssuer = true,//是否验证颁发者
ValidIssuer = "dotnet-jwt",//颁发者
ValidateAudience = true, //是否验证接收者
ValidAudience = "StudentAPI",//接收者
ValidateLifetime = true,//是否验证失效时间
};
//捕获Token过期事件
j.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
//出现此类异常。
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
//在响应头中添加isexpired:true键值对。
context.Response.Headers.Add("isexpired", "true");
}
return Task.CompletedTask;
}
};
});
(2)捕获 Token 事件,处理refreshToken:
//捕获Token过期事件
j.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
//出现此类异常。
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
//在响应头中添加isexpired:true键值对。
context.Response.Headers.Add("isexpired", "true");
}
return Task.CompletedTask;
}
};
认证服务器
创建项目
新建一个“AspNetCore 空” 项目,名为:DotNet.WebApi.Jwt.Authentication
依赖包
添加依赖包:
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.3" />
标签:Core,builder,Jwt,context,Services,new,true,app,AspNet
From: https://www.cnblogs.com/easy5weikai/p/17201236.html