.NET鉴权授权
gitee仓储地址
---------------------------------2022-03-30分界线-----------------------------------
一种是cookie鉴权授权,一种是token鉴权授权,先把权限授予它,才能鉴定它的权限是否符合我的权限校验
一.鉴权cookie方式
1.在program中添加鉴权授权中间件
2.在控制器某个方法上添加鉴权特性
3.在program中添加
点击查看代码
builder.Services.AddAuthentication("Cookies").AddCookie(o =>
{
o.LoginPath = "/Login/NoLogin";//鉴权不通过就跳到以下路径
});
4.添加一个控制器LoginController
点击查看代码
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace AuthDemo.Api.Controllers
{
[Route("[controller]/[action]")]
[ApiController]
public class LoginController : ControllerBase
{
[HttpGet]
public async Task<string> NoLoginAsync()
{
return "您还没有登录!";
}
}
}
5.在login控制器中添加一个方法
点击查看代码
[HttpPost]
public async Task<string> LoginSucess(string userName,string password)
{
//判断当前的用户名和密码
if (userName=="Ace"&&password=="666")
{
//如果符合当前条件,则实例化一个实体,保存当前数据
ClaimsIdentity claimsIdentity = new ClaimsIdentity("Ctm");
claimsIdentity.AddClaim(new ( ClaimTypes.Name, userName));
claimsIdentity.AddClaim(new(ClaimTypes.NameIdentifier, "1"));
//cookies与program添加的鉴权架构一致
await HttpContext.SignInAsync("Cookies",new ClaimsPrincipal(claimsIdentity));
return "登录成功!";
}
else
{
return "登录失败!";
}
}
二.自定义token鉴权 自定义鉴权策略
1.新增一个文件夹CtmAuthentication,新增一个类文件TokenAuthenticationHandler,继承于IAuthenticationHandler接口,实现接口
2.TokenAuthenticationHandler类里的代码如下
点击查看代码
using Microsoft.AspNetCore.Authentication;
using System.Security.Claims;
namespace AuthDemo.Api.CtmAuthentication
{
public class TokenAuthenticationHandler : IAuthenticationHandler
{
private AuthenticationScheme _scheme;
private HttpContext _httpContext;
/// <summary>
/// 鉴权初始化
/// </summary>
/// <param name="scheme">鉴权架构名称</param>
/// <param name="context">HttpContext</param>
/// <returns></returns>
public async Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
_scheme = scheme;
_httpContext = context;
}
/// <summary>
/// 鉴权
/// </summary>
/// <returns></returns>
public async Task<AuthenticateResult> AuthenticateAsync()
{
string token = _httpContext.Request.Headers["Authorization"];
if (token=="jaden")
{
ClaimsIdentity claimsIdentity = new("ctm");
claimsIdentity.AddClaims(new List<Claim>
{
new Claim(ClaimTypes.Name,"jaden"),
new Claim(ClaimTypes.NameIdentifier,"6")
});
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
return await Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal,_scheme.Name)));
}
return await Task.FromResult(AuthenticateResult.Fail("token错误,请重新登录"));
}
/// <summary>
/// 未登录操作
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
public async Task ChallengeAsync(AuthenticationProperties? properties)
{
_httpContext.Response.Redirect("/Login/NoLogin");
}
/// <summary>
/// 鉴权失败的操作
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
public async Task ForbidAsync(AuthenticationProperties? properties)
{
_httpContext.Response.StatusCode = 403;
}
}
}
3.修改program中的代码,如下
点击查看代码
using AuthDemo.Api.CtmAuthentication;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
#region 注册鉴权架构
//cookie
//builder.Services.AddAuthentication("Cookies").AddCookie(o =>
//{
// o.LoginPath = "/Login/NoLogin";//鉴权不通过就跳到以下路径
//});
//自定义token验证
builder.Services.AddAuthentication(op =>
{
//把自定义的鉴权方案添加到鉴权架构中
//token是个名字,下面的代表Scheme name方案名字
op.AddScheme<TokenAuthenticationHandler>("token","ctmToken");
op.DefaultAuthenticateScheme = "token";
op.DefaultChallengeScheme = "token";
op.DefaultForbidScheme = "token";
});
#endregion
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
//鉴权
app.UseAuthentication();
//授权
app.UseAuthorization();
app.MapControllers();
app.Run();
4.然后用postman或者apipost中测试,token中输入一些字符,发现token中存在这些字符,下面让我们继续改造,其实token就是存在我们发送请求的head文件里的
三.授权策略
1.在program中的鉴权策略下添加如下代码
点击查看代码
/*
自定义授权时,
控制器上加的Authorize授权,
后面记得加当前名称'MyPolicy',
才能匹配到当前的授权方案(一般配置为常量)
*/
//自定义授权
builder.Services.AddAuthorization(op =>
{
//判断当前的授权方案的
op.AddPolicy(AuthorizationConts.MyPolicy, p => p.RequireClaim(ClaimTypes.NameIdentifier, "6"));
});
新增一个常量类AuthorizationConts,存放一个常量MyPolicy,值也是这个
2.在WeatherForecastController控制器中的Authorize鉴权特性中添加常量,代表的意思是鉴权时匹配我们自定义的鉴权
代码如下:
点击查看代码
using AuthDemo.Api.Consts;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace AuthDemo.Api.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[Authorize(AuthorizationConts.MyPolicy)]
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}
经过以上改造就完成了自定义授权
四.授权断言
1.什么叫授权断言?
首先判定你当前用户有没有这个身份,比如说你的name有没有,有我则继续判断匹配不匹配,没有则直接报错
2.program中的自定义授权改为如下代码
点击查看代码
//自定义授权
builder.Services.AddAuthorization(op =>
{
//判断当前的授权方案的
//op.AddPolicy(AuthorizationConts.MyPolicy, p => p.RequireClaim(ClaimTypes.NameIdentifier, "6"));
//授权断言
//先判断user的类型是不是NameIdentifier,如果是,则判断当前值匹配不匹配
//如果不是则直接报错
op.AddPolicy(AuthorizationConts.MyPolicy,p=>
p.RequireAssertion(
a=>a.User.HasClaim(c=>c.Type==ClaimTypes.NameIdentifier) &&
a.User.Claims.First(c=>c.Type.Equals(ClaimTypes.NameIdentifier)).Value=="6"
));
});
---------------------------------2022-03-31分界线-----------------------------------
---------------------------------2022-04-02分界线-----------------------------------
五.自定义授权与双授权策略(多scheme)
合起来的方案
1.创建一个CtmAuthorizations文件夹,创建一个MyAuthorizationHandler类,
MyAuthorizationHandler继承于AuthorizationHandler泛型抽象类
代码如下
点击查看代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
namespace AuthDemo.Api.CtmAuthorizations
{
public class MyAuthorizationHandler : AuthorizationHandler<MyAuthorizationHandler>, IAuthorizationRequirement
{
private readonly string userId;
public MyAuthorizationHandler(string userId)
{
this.userId = userId;
}
/// <summary>
/// 重写 AuthorizationHandler 父类中的 HandleRequirementAsync 方法
/// </summary>
/// <param name="context"></param>
/// <param name="requirement"></param>
/// <returns></returns>
protected override async Task HandleRequirementAsync(
AuthorizationHandlerContext context,
MyAuthorizationRequirement requirement)
{
if (context.User.HasClaim(c => c.Type == ClaimTypes.NameIdentifier)
&& context.User.Claims.First(c => c.Type.Equals(ClaimTypes.NameIdentifier)).Value == userId)
{
context.Succeed(requirement);
}
}
}
}
2.program中的代码为:
点击查看代码
using System.Security.Claims;
using AuthDemo.Api.Consts;
using AuthDemo.Api.CtmAuthentication;
using AuthDemo.Api.CtmAuthorizations;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
#region 注册鉴权架构
//cookie
//builder.Services.AddAuthentication("Cookies").AddCookie(o =>
//{
// o.LoginPath = "/Login/NoLogin";//鉴权不通过就跳到以下路径
//});
//自定义token验证 鉴权策略
builder.Services.AddAuthentication(op =>
{
//把自定义的鉴权方案添加到鉴权架构中
//token是个名字,下面的代表Scheme name方案名字
op.AddScheme<TokenAuthenticationHandler>("token", "ctmToken");
op.DefaultAuthenticateScheme = "token";
op.DefaultChallengeScheme = "token";
op.DefaultForbidScheme = "token";
});
/*
自定义授权时,
控制器上加的Authorize授权,
后面记得加当前名称'MyPolicy',
才能匹配到当前的授权方案(一般配置为常量)
*/
//自定义授权
// builder.Services.AddAuthorization(op =>
// {
// //判断当前的授权方案的
// //op.AddPolicy(AuthorizationConts.MyPolicy, p => p.RequireClaim(ClaimTypes.NameIdentifier, "6"));
// //授权断言
// //先判断user的类型是不是NameIdentifier,如果是,则判断当前值匹配不匹配
// //如果不是则直接报错
// op.AddPolicy(AuthorizationConts.MyPolicy, p =>
// p.RequireAssertion(
// a => a.User.HasClaim(c => c.Type == ClaimTypes.NameIdentifier) &&
// a.User.Claims.First(c => c.Type.Equals(ClaimTypes.NameIdentifier)).Value == "6"
// ));
// });
//自定义授权
builder.Services.AddAuthorization(op =>
{
op.AddPolicy(AuthorizationConts.MyPolicy, p => p.Requirements.Add(new MyAuthorizationHandler("6")));
});
#endregion
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
//鉴权
app.UseAuthentication();
//授权
app.UseAuthorization();
app.MapControllers();
app.Run();
---------------------------------2022-04-04分界线-----------------------------------
分开的方案
在使用双授权方案时,这两个策略必须同事通过才可以,否则授权失败
双授权方案与单授权方案基本一致,唯一不一样的就是注册policy的时候,注册两次,控制器的鉴权验证也写两次,将MyAuthorizationHandler复制一次即可,
将自定义授权方式换了一个
六.多鉴权架构
下午写这段
多鉴权架构下,只要成功一个,那么鉴权即认为成功
在控制器下加这段,并且打开program中cookie鉴权的注释
[Authorize(AuthenticationSchemes = $"token,Cookies")]
持续更新
七.授权和鉴权的绑定
1.修改program中的代码
点击查看代码
using System.Security.Claims;
using AuthDemo.Api.Consts;
using AuthDemo.Api.CtmAuthentication;
using AuthDemo.Api.CtmAuthorizations;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
#region 注册鉴权架构
//cookie
builder.Services.AddAuthentication("Cookies").AddCookie(o =>
{
o.LoginPath = "/Login/NoLogin";//鉴权不通过就跳到以下路径
});
//自定义token验证 鉴权策略
builder.Services.AddAuthentication(op =>
{
//把自定义的鉴权方案添加到鉴权架构中
//token是个名字,下面的代表Scheme name方案名字
op.AddScheme<TokenAuthenticationHandler>("token", "ctmToken");
// op.DefaultAuthenticateScheme = "token";
op.DefaultChallengeScheme = "token";
op.DefaultForbidScheme = "token";
});
/*
自定义授权时,
控制器上加的Authorize授权,
后面记得加当前名称'MyPolicy',
才能匹配到当前的授权方案(一般配置为常量)
*/
//自定义授权
// builder.Services.AddAuthorization(op =>
// {
// //判断当前的授权方案的
// //op.AddPolicy(AuthorizationConts.MyPolicy, p => p.RequireClaim(ClaimTypes.NameIdentifier, "6"));
// //授权断言
// //先判断user的类型是不是NameIdentifier,如果是,则判断当前值匹配不匹配
// //如果不是则直接报错
// op.AddPolicy(AuthorizationConts.MyPolicy, p =>
// p.RequireAssertion(
// a => a.User.HasClaim(c => c.Type == ClaimTypes.NameIdentifier) &&
// a.User.Claims.First(c => c.Type.Equals(ClaimTypes.NameIdentifier)).Value == "6"
// ));
// });
//自定义授权
builder.Services.AddAuthorization(op =>
{
op.AddPolicy(AuthorizationConts.MyPolicy,
p => p.AddAuthenticationSchemes("token").Requirements.Add(new MyAuthorizationHandler("6")));
// op.AddPolicy(AuthorizationConts.MyPolicy, p => p.Requirements.Add(new MyAuthorizationHandler("6")));
op.AddPolicy(AuthorizationConts.MyPolicy2, p => p.AddAuthenticationSchemes("Cookies").Requirements.Add(new MyAuthorizationHandler2("Ace")));
});
#endregion
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
//鉴权
app.UseAuthentication();
//授权
app.UseAuthorization();
app.MapControllers();
app.Run();
将poliy中添加schemes,为token,并注释默认scheme即可
2.注意scheme策略名称需要一直,鉴权和授权策略名称是一致的
修改控制器中的代码,输入你要鉴权的方案
点击查看代码
[Authorize(AuthorizationConts.MyPolicy2)]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
这里我用的是mypolicy2的鉴权方案,当你用哪个鉴权方案时,它就用哪个鉴权,并且对它进行授权
--------------------------------------2022-04-05分界线--------------------------------------------
八.session授权绑定鉴权
session本身是个字典,并且是个作用域生命周期,session存在缓存中,并可以设置过期时间
key:sessionId,value:Dictonary<sessionKey,SessionValue>(字符串字典)
1.首先要想实现seesion自定义实现,必须用到缓存(MemoryCache),并且新增一个文件夹Core,新增一个MySession及IMySession接口,MySession继承于IMySession
program类代码如下:
点击查看代码
using System.Security.Claims;
using AuthDemo.Api.Consts;
using AuthDemo.Api.Core;
using AuthDemo.Api.CtmAuthentication;
using AuthDemo.Api.CtmAuthorizations;
using Microsoft.Extensions.Caching.Memory;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// builder.Services.AddSingleton<IMemoryCache, MemoryCache>();
builder.Services.AddMemoryCache();
builder.Services.AddScoped<IMySession, MySession>();
#region 注册鉴权架构
//cookie
// builder.Services.AddAuthentication("Cookies").AddCookie(o =>
// {
// o.LoginPath = "/Login/NoLogin";//鉴权不通过就跳到以下路径
// });
//自定义token验证 鉴权策略
builder.Services.AddAuthentication(op =>
{
//把自定义的鉴权方案添加到鉴权架构中
//token是个名字,下面的代表Scheme name方案名字
op.AddScheme<SessionAuthenicationHandler>("session", "ctmSession");
op.DefaultAuthenticateScheme = "session";
op.DefaultChallengeScheme = "session";
op.DefaultForbidScheme = "session";
});
/*
自定义授权时,
控制器上加的Authorize授权,
后面记得加当前名称'MyPolicy',
才能匹配到当前的授权方案(一般配置为常量)
*/
//自定义授权
// builder.Services.AddAuthorization(op =>
// {
// //判断当前的授权方案的
// //op.AddPolicy(AuthorizationConts.MyPolicy, p => p.RequireClaim(ClaimTypes.NameIdentifier, "6"));
// //授权断言
// //先判断user的类型是不是NameIdentifier,如果是,则判断当前值匹配不匹配
// //如果不是则直接报错
// op.AddPolicy(AuthorizationConts.MyPolicy, p =>
// p.RequireAssertion(
// a => a.User.HasClaim(c => c.Type == ClaimTypes.NameIdentifier) &&
// a.User.Claims.First(c => c.Type.Equals(ClaimTypes.NameIdentifier)).Value == "6"
// ));
// });
//自定义授权
// builder.Services.AddAuthorization(op =>
// {
// op.AddPolicy(AuthorizationConts.MyPolicy,
// p => p.AddAuthenticationSchemes("token").Requirements.Add(new MyAuthorizationHandler("6")));
// // op.AddPolicy(AuthorizationConts.MyPolicy, p => p.Requirements.Add(new MyAuthorizationHandler("6")));
// op.AddPolicy(AuthorizationConts.MyPolicy2, p => p.AddAuthenticationSchemes("Cookies").Requirements.Add(new MyAuthorizationHandler2("Ace")));
// });
#endregion
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
//鉴权
app.UseAuthentication();
//授权
app.UseAuthorization();
app.MapControllers();
app.Run();
具体的思路,在代码中已经详细标明了
2.MySession和IMySession接口代码如下:
IMySession
using Microsoft.Extensions.Caching.Memory;
namespace AuthDemo.Api.Core
{
public interface IMySession
{
string GetString(string key);
void InitSession(string sessionId, IMemoryCache memoryCache);
void SetString(string key, string value);
}
}
MySession
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
namespace AuthDemo.Api.Core
{
public class MySession : IMySession
{
/*
1.session是这样去保存数据的,每个用户都有一个sessionId,
2.根据sessionId去获取用户的数据
3.每个用户的数据保存在内存中,这样可以让session更短(就是浏览器的缓存中)
4.sessionId是唯一的,每个用户的sessionId是不一样的
5.sessionId是在第一次访问的时候生成的,第一次访问后,sessionId就会被保存在cookie中
6.所以我们需要在我们设计的session类中,定义一个私有sessionId,并定义一个缓存
7.这样在初始化Session的时候,将初始化Session的方法调用一下,把SessionId和缓存传进去
8.在获取数据的时候,根据sessionId去缓存中获取数据
9.在设置数据的时候,根据sessionId去缓存中设置数据
*/
private string sessionId;
private IMemoryCache memoryCache;
/// <summary>
/// 初始化Session,在鉴权验证方法中被调用
/// </summary>
/// <param name="sessionId"></param>
/// <param name="memoryCache"></param>
public void InitSession(string sessionId, IMemoryCache memoryCache)
{
this.memoryCache = memoryCache;
this.sessionId = sessionId;
}
/// <summary>
/// 通过key获取存储的值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string GetString(string key)
{
// 获取SeesionId 并根据SeesionId拿到当前用户存储的键值对
if (memoryCache.TryGetValue(sessionId, out Dictionary<string, string> dic))
{
return dic[key];
}
else
{
return default;
}
}
public void SetString(string key, string value)
{
// 获取SeesionId 并根据SeesionId拿到当前用户存储的键值对
if (memoryCache.TryGetValue(sessionId, out Dictionary<string, string> dic))
{
dic[key] = value;
}
}
}
}
3.SessionAuthenicationHandler代码如下:
SessionAuthenicationHandler
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using AuthDemo.Api.Core;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Caching.Memory;
namespace AuthDemo.Api.CtmAuthentication
{
public class SessionAuthenicationHandler : IAuthenticationHandler
{
/// <summary>
/// 定义一个缓存
/// </summary>
private readonly IMemoryCache _cache;
/// <summary>
/// 定义一个自定义的Session
/// </summary>
private readonly IMySession _session;
/// <summary>
/// 定义一个SessionId
/// </summary>
private string _sessionId;
/// <summary>
/// 定义上下文
/// </summary>
private HttpContext _context;
/// <summary>
/// 定义鉴权策略
/// </summary>
public AuthenticationScheme _scheme;
/// <summary>
/// 构造函数传入缓存,及session
/// </summary>
/// <param name="cache"></param>
/// <param name="session"></param>
public SessionAuthenicationHandler(IMemoryCache cache, IMySession session)
{
this._session = session;
this._cache = cache;
}
/// <summary>
///
/// </summary>
/// <param name="scheme"></param>
/// <param name="context"></param>
/// <returns></returns>
public async Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
//1.初始化时将策略赋值,将上下文赋值
this._scheme = scheme;
this._context = context;
//从上下文中的cookie取值,没有则创建一个
//判断当前缓存没有seesionid并且实际的数据也没有,则创建一个新的sessionid
if (!TryGetSession(out string id) || !_cache.TryGetValue(_sessionId, out Dictionary<string, string> value))
{
//创建一个sessionid,为guid
var sessionId = Guid.NewGuid().ToString();
_sessionId = sessionId;
//将上下文中的返回值的cookie,设置一个sessionid
_context.Response.Cookies.Append(".AspNetCore.Session", sessionId);
//将sessionid当作键值,将空的字典当作值,并设置过期时间
_cache.Set<Dictionary<string, string>>(sessionId, new Dictionary<string, string>(), TimeSpan.FromMinutes(20));
}
}
/// <summary>
/// 从上下文中的cookie中取值,输出sessionId
/// 将sesionid赋值到当前私有变量sessionId中,
/// 如果能获取到值则返回true,否则返回false
/// </summary>
/// <param name="sessionId"></param>
/// <returns></returns>
private bool TryGetSession(out string sessionId)
{
var hasSession = _context.Request.Cookies.TryGetValue(".AspNetCore.Session", out sessionId);
_sessionId = sessionId;
return hasSession;
}
/// <summary>
/// 鉴权方法
/// </summary>
/// <returns></returns>
public async Task<AuthenticateResult> AuthenticateAsync()
{
//从缓存中获取sessionid,如果没有则返回false
if (_cache.TryGetValue(_sessionId, out Dictionary<string, string> value))
{
//将当前sessionId和键值对组成新的键值对,存入缓存中,并设置过期时间为20分钟
_cache.Set<Dictionary<string, string>>(_sessionId, value, TimeSpan.FromMinutes(20));
//调用session的初始化方法,将sessionId和缓存中的键值对传入
_session.InitSession(_sessionId, _cache);
//将当前sessionId赋值给ClaimsPrincipal
ClaimsIdentity claimsIdentity = new("ctm");
claimsIdentity.AddClaims(new List<Claim>
{
new Claim(ClaimTypes.NameIdentifier,_sessionId)
});
//最终返回成功的结果
return await Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(claimsIdentity), null, _scheme.Name)));
}
else
{
return await Task.FromResult(AuthenticateResult.Fail("Session已经过期"));
}
}
public async Task ChallengeAsync(AuthenticationProperties properties)
{
_context.Response.Redirect("/Login/NoLogin");
}
public async Task ForbidAsync(AuthenticationProperties properties)
{
_context.Response.StatusCode = 403;
}
}
}
小一周完成了