交流QQ群:555913397
有什么问题可以加群大家一起交流
创建自定义的cookie鉴权 授权 管道…相信很多人都没搞清楚,这里为大家揭开心中的疑惑.废话不多说,上代码…
1.创建一个自定义的鉴权 授权 签发Ticket的Hanlder
这里实现登录签发Ticket 退出登录销毁Ticket 鉴权 授权等管理
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
namespace CoreMvc.Utinity.Authentications
{
public class CoreMvcAuthenticationHandler : IAuthenticationHandler, IAuthenticationSignInHandler, IAuthenticationSignOutHandler
{
public AuthenticationScheme Scheme { get; private set; }
protected HttpContext Context { get; private set; }
/// <summary>
/// 鉴权
/// </summary>
/// <returns></returns>
public async Task<AuthenticateResult> AuthenticateAsync()
{
string cookie = Context.Request.Cookies["AuthenticationScheme"];
if (string.IsNullOrEmpty(cookie))
{
return AuthenticateResult.NoResult();
}
return await Task.FromResult(AuthenticateResult.Success(Deserialize(cookie)));
}
/// <summary>
/// 没有登录
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
public Task ChallengeAsync(AuthenticationProperties properties)
{
Context.Response.Redirect("/home/login");
return Task.CompletedTask;
}
/// <summary>
/// 没有权限禁止访问
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
public Task ForbidAsync(AuthenticationProperties properties)
{
Context.Response.StatusCode = 403;
return Task.CompletedTask;
}
/// <summary>
/// 初始化鉴权Handler
/// </summary>
/// <param name="scheme">鉴权组合</param>
/// <param name="context">http上下文</param>
/// <returns></returns>
public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
Scheme = scheme;
Context = context;
return Task.CompletedTask;
}
/// <summary>
/// 登录
/// </summary>
/// <param name="user"></param>
/// <param name="properties"></param>
/// <returns></returns>
public Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
{
AuthenticationTicket ticket = new AuthenticationTicket(user, properties, Scheme.Name);
Context.Response.Cookies.Append("AuthenticationScheme", Serialize(ticket));
return Task.CompletedTask;
}
/// <summary>
/// 退出
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
public Task SignOutAsync(AuthenticationProperties properties)
{
Context.Response.Cookies.Delete("AuthenticationScheme");
return Task.CompletedTask;
}
/// <summary>
/// 反序列化Ticket
/// </summary>
/// <param name="ticket">字符串Ticket</param>
/// <returns></returns>
public AuthenticationTicket Deserialize(string ticket)
{
byte[] byteTicket = Encoding.Default.GetBytes(ticket);
return TicketSerializer.Default.Deserialize(byteTicket);
}
/// <summary>
/// 序列化Ticket
/// </summary>
/// <param name="ticket">AuthenticationTicket</param>
/// <returns></returns>
public string Serialize(AuthenticationTicket ticket)
{
byte[] byteTicket = TicketSerializer.Default.Serialize(ticket);
return Encoding.Default.GetString(byteTicket);
}
}
}
2.注册自定义Handler
在Startup.cs的 ConfigureServices(IServiceCollection services)里注册
//注册自定义Handler
services.AddAuthenticationCore(options =>
{
options.AddScheme<CoreMvcAuthenticationHandler>("AuthenticationScheme", "AuthenticationScheme");
});
3.注册鉴权 授权 创建Ticket管道
在Startup.cs的Configure(IApplicationBuilder app, IWebHostEnvironment env)里注册
//拦截登录页面
app.Map("/Home/Login", buider =>
//创建Ticket中间件
buider.UseAddAuthenticationCreate());
//鉴权中间件
app.UseAddAuthentication();
//授权中间件
app.UseAddAuthorizetion();
//访问受保护资源
app.Map("/resouce", builder => builder.Run(async (context) =>
{
await context.Response.WriteAsync($"welcome to .net core {context.User.Identity.Name}");
}));
app.Run(async (HttpContext context) =>
{
await context.Response.WriteAsync("Hello World,success!");
});
4.中间件扩展方法
通过这个扩展方法可以把中间件B格提升一部分.
using System;
using CoreMvc.Utinity.MiddleWare.Authentications;
using Microsoft.AspNetCore.Builder;
namespace CoreMvc.Utinity.MiddleWare
{
public static class MiddleWareExtension
{
/// <summary>
/// 创建Ticket中间件
/// </summary>
/// <param name="app">IApplicationBuilder</param>
/// <returns></returns>
public static IApplicationBuilder UseAddAuthenticationCreate(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
return app.UseMiddleware<AuthenticationCreate>();
}
/// <summary>
/// 鉴权中间件
/// </summary>
/// <param name="app">IApplicationBuilder</param>
/// <returns></returns>
public static IApplicationBuilder UseAddAuthentication(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
return app.UseMiddleware<Authentication>();
}
/// <summary>
/// 授权中间件
/// </summary>
/// <param name="app">IApplicationBuilder</param>
/// <returns></returns>
public static IApplicationBuilder UseAddAuthorizetion(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
return app.UseMiddleware<Authorization>();
}
}
}
5. 创建Ticket中间件
这里可以在登陆成功后赋予相应权限.
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
namespace CoreMvc.Utinity.MiddleWare.Authentications
{
/// <summary>
/// 创建鉴权Ticket
/// </summary>
public class AuthenticationCreate
{
private readonly RequestDelegate _next;
public AuthenticationCreate(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
ClaimsIdentity claimsIdentity = new ClaimsIdentity(new List<Claim>
{
new Claim(ClaimTypes.Name, "fqydhk"),
new Claim(ClaimTypes.MobilePhone, "13151********")
}, "login");
await context.SignInAsync("AuthenticationScheme", new ClaimsPrincipal(claimsIdentity));
await _next(context);
}
}
}
6.鉴权中间件
通过这个中间件来实现查询是否有Ticket,如果有就放行
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
namespace CoreMvc.Utinity.MiddleWare.Authentications
{
/// <summary>
/// 鉴权
/// </summary>
public class Authentication
{
private readonly RequestDelegate _next;
public Authentication(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
AuthenticateResult result = await context.AuthenticateAsync("AuthenticationScheme");
if (null != result?.Principal)
{
context.User = result.Principal;
await _next(context);
}
else
{
await context.ChallengeAsync("AuthenticationScheme");
}
}
}
}
7.授权中间件
通过这个中间件来实现具体的权限验证,验证通过就直接放行,一般用来判断角色是否有权使用具体业务
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
namespace CoreMvc.Utinity.MiddleWare.Authentications
{
/// <summary>
/// 授权
/// </summary>
public class Authorization
{
private readonly RequestDelegate _next;
public Authorization(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
System.Security.Claims.ClaimsPrincipal user = context.User;
if (user.Identity.Name == "fqydhk")
{
await _next(context);
}
else
{
await context.ForbidAsync("AuthenticationScheme");
}
}
}
}