1、自定义权限需要扩展 Microsoft.AspNetCore.Authentication 实现一套接口
IAuthenticationHandler, IAuthenticationSignInHandler, IAuthenticationSignOutHandler
public classMyAuthenticationHandler : IAuthenticationHandler, IAuthenticationSignInHandler, IAuthenticationSignOutHandler
{public AuthenticationScheme Scheme { get; private set; }protected HttpContext Context { get; private set; }publicTask InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
Scheme=scheme;
Context=context;returnTask.CompletedTask;
}publicTask ChallengeAsync(AuthenticationProperties properties)
{
Context.Response.Redirect("/Account/login");returnTask.CompletedTask;
}public async TaskAuthenticateAsync()
{var result = await Task.Run(() =>{var cookie = Context.Request.Cookies["myCookie"];if (string.IsNullOrEmpty(cookie))
{returnAuthenticateResult.NoResult();
}return AuthenticateResult.Success(this.Deserialize(cookie));
});returnresult;
}publicTask ForbidAsync(AuthenticationProperties properties)
{
Context.Response.StatusCode= 403;returnTask.CompletedTask;
}publicTask SignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
{var ticket = newAuthenticationTicket(user, properties, Scheme.Name);
Context.Response.Cookies.Append("myCookie", Serialize(ticket));returnTask.CompletedTask;
}publicTask SignOutAsync(AuthenticationProperties properties)
{
Context.Response.Cookies.Delete("myCookie");returnTask.CompletedTask;
}private stringSerialize(AuthenticationTicket ticket)
{byte[] byteTicket =TicketSerializer.Default.Serialize(ticket);returnSystem.Text.Encoding.Default.GetString(byteTicket);
}private AuthenticationTicket Deserialize(stringticket)
{byte[] byteTicket =System.Text.Encoding.Default.GetBytes(ticket);returnTicketSerializer.Default.Deserialize(byteTicket);
}
}
2、在 ConfigureServices 中注册服务
//This method gets called by the runtime. Use this method to add services to the container.
public voidConfigureServices(IServiceCollection services)
{services.AddAuthentication(
option=>{
option.DefaultScheme= "myScheme";
option.AddScheme("myScheme", "demo scheme");
});
services.Configure(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.AddSession();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
3、在 void Configure(IApplicationBuilder app, IHostingEnvironment env) 中使用权限检查
app.UseAuthentication();
4、在 Controller 中实现自己的 Login 、Logout
[AllowAnonymous]public async void Login(string username, stringpassword)
{var claimIdentity = new ClaimsIdentity("CustomApiKeyAuth");
claimIdentity.AddClaim(newClaim(ClaimTypes.Name, username));
claimIdentity.AddClaim(new Claim(ClaimTypes.Role, "Admin"));await HttpContext.SignInAsync("myScheme", newClaimsPrincipal(claimIdentity));await HttpContext.Response.WriteAsync($"Hello {username} login!");
}public async voidLogout()
{await HttpContext.SignOutAsync("myScheme");
}
5、在 Controller 中使用权限检查特性
[Authorize(Roles = "Admin")]public voidTest()
{var user =HttpContext.User;
HttpContext.Response.WriteAsync($"Test {user.Identity.Name}!");
}
6、测试
在浏览器上输入 https://localhost:44318/account/login?username="aaa"
系统输出: Hello "aaa" login!
在浏览器上输入 https://localhost:44318/account/test
系统输出 : Test "aaa"!
成功运行了。
7、结束语
虽然只是简单的框架代码,但实现了完整的流程控制。方便初学者。
需要源代码的朋友点这里下载。
8、参考资料