实体模型
| public class BaseModel |
| { |
| public int Id { get; set;} |
| } |
| public class Authorization : BaseModel |
| { |
| public string Route { get; set; } |
| public string AuthorizationName { get; set; } |
| } |
| public class User : BaseModel |
| { |
| public string UserName { get; set; } |
| public string Password { get; set; } |
| } |
| public class UserAuthorizationMapping : BaseModel |
| { |
| public int UserId { get; set; } |
| public int AuthorizationId { get; set; } |
| } |
自定义Session
| public interface IMySession |
| { |
| void InitSession(IMemoryCache memoryCache, string sessionId); |
| string? GetString(string key); |
| void SetString(string key, string value); |
| } |
| |
| public class MySession : IMySession |
| { |
| private IMemoryCache _memoryCache; |
| private string _sessionId; |
| public void InitSession(IMemoryCache memoryCache, string sessionId) |
| { |
| _sessionId = sessionId; |
| _memoryCache = memoryCache; |
| } |
| public string? GetString(string key) |
| { |
| |
| if(_memoryCache.TryGetValue(_sessionId,out Dictionary<string,string>? dic)) |
| { |
| if(dic == null) |
| { |
| return null; |
| } |
| if(dic.TryGetValue(key,out string? dicValue)) |
| { |
| return dicValue; |
| } |
| } |
| return null; |
| } |
| public void SetString(string key,string value) |
| { |
| if (_memoryCache.TryGetValue(_sessionId, out Dictionary<string, string>? dic)) |
| { |
| if (dic != null) |
| { |
| dic[key] = value; |
| } |
| } |
| } |
| } |
| |
自定义鉴权架构
| public class SessionAuthenicationHandler : IAuthenticationHandler |
| { |
| private readonly IMemoryCache _cache; |
| private readonly IMySession _session; |
| private AuthenticationScheme _scheme; |
| private HttpContext _context; |
| private string _sessionId; |
| |
| public SessionAuthenicationHandler(IMemoryCache cache, IMySession session) |
| { |
| _cache = cache; |
| _session = session; |
| } |
| |
| |
| |
| |
| |
| |
| |
| public async Task InitializeAsync(AuthenticationScheme scheme, HttpContext context) |
| { |
| _scheme = scheme; |
| _context = context; |
| if (!TryGetSession(out string id) || !_cache.TryGetValue(_sessionId, out var cookie)) |
| { |
| var sessionId = Guid.NewGuid().ToString(); |
| _sessionId = sessionId; |
| context.Response.Cookies.Append(".AspNetCore.Sessions", sessionId); |
| _cache.Set<Dictionary<string, string>>(_sessionId, new Dictionary<string, string>(), TimeSpan.FromMinutes(1)); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| public Task<AuthenticateResult> AuthenticateAsync() |
| { |
| |
| if(_cache.TryGetValue(_sessionId,out Dictionary<string,string> value)) |
| { |
| |
| _cache.Set<Dictionary<string,string>>(_sessionId,value,TimeSpan.FromMinutes(1)); |
| |
| _session.InitSession(_cache,_sessionId); |
| |
| _context.Items["session"] = _session; |
| |
| ClaimsIdentity claimsIdentity = new ClaimsIdentity("Ctm"); |
| claimsIdentity.AddClaims( |
| new List<Claim> |
| { |
| new Claim(ClaimTypes.NameIdentifier,_sessionId) |
| } |
| ); |
| return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(claimsIdentity),null,_scheme.Name))); |
| }else |
| { |
| return 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; |
| } |
| |
| private bool TryGetSession(out string id) |
| { |
| var has = _context.Request.Cookies.TryGetValue(".AspNetCore.Sessions",out id); |
| _sessionId = id; |
| return has; |
| } |
| |
| } |
自定义授权
| public class CtmAuthorizationFilter : Attribute, IAuthorizationFilter |
| { |
| public void OnAuthorization(AuthorizationFilterContext context) |
| { |
| var session = context.HttpContext.Items["session"] as IMySession; |
| var route = context.HttpContext.Request.Path.Value; |
| var auth = session.GetString("Auth"); |
| if(auth != null) |
| { |
| var aurhorizations = JsonConvert.DeserializeObject<List<Authorization>>(auth); |
| if(aurhorizations == null || aurhorizations.Count < 1) |
| { |
| context.Result = new JsonResult("没有录入权限数据") { StatusCode = 403 }; |
| } |
| if (aurhorizations.Any(x => x.Route != route)) |
| { |
| context.Result = new JsonResult("无权限") { StatusCode = 403 }; |
| } |
| }else |
| { |
| context.Result = new JsonResult("请先登录") { StatusCode = 403 }; |
| } |
| } |
| } |
| |
注册
| builder.Services.AddSingleton<IMemoryCache,MemoryCache>(); |
| builder.Services.AddScoped<IMySession,MySession>(); |
| builder.Services.AddAuthentication(opt => |
| { |
| opt.AddScheme<SessionAuthenicationHandler>("session","sessionScheme"); |
| opt.DefaultChallengeScheme = "session"; |
| opt.DefaultAuthenticateScheme = "session"; |
| opt.DefaultForbidScheme = "session"; |
| }); |
| |
| app.UseAuthentication(); |
| app.UseAuthorization(); |
使用
| public class LoginController : BaseController |
| { |
| private readonly LoginBLL _loginBLL; |
| public LoginController(LoginBLL loginBLL) |
| { |
| _loginBLL = loginBLL; |
| } |
| [HttpGet("CheckLogin")] |
| public async Task<bool> CheckLoginAsync(string userName, string password) |
| { |
| var user = await _loginBLL.CheckLoginAsync(userName, password); |
| if (user == null) |
| { |
| return false; |
| } |
| var authorizations = await _loginBLL.GetAuthorizationsAsync(user.Id); |
| Session.SetString("Auth", JsonConvert.SerializeObject(authorizations)); |
| return true; |
| } |
| } |
| |
| public class TestController : BaseController |
| { |
| [CtmAuthorizationFilter] |
| [HttpGet("GetTime")] |
| public async Task<string> GetTimeAsync() |
| { |
| return await Task.FromResult(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); |
| } |
| } |
结果
1.在不登录的情况下访问GetTime

2.先登录,再访问GetTime

3.把数据库录入的路径改为错误的路径

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?