交流QQ群:555913397
有什么问题可以加群大家一起交流
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; }
///
/// 鉴权
///
///
public async Task AuthenticateAsync()
{
string cookie = Context.Request.Cookies["AuthenticationScheme"];
if (string.IsNullOrEmpty(cookie))
{
return AuthenticateResult.NoResult();
}
return await Task.FromResult(AuthenticateResult.Success(Deserialize(cookie)));
}
///
/// 没有登录
///
///
///
public Task ChallengeAsync(AuthenticationProperties properties)
{
Context.Response.Redirect("/home/login");
return Task.CompletedTask;
}
///
/// 没有权限禁止访问
///
///
///
public Task ForbidAsync(AuthenticationProperties properties)
{
Context.Response.StatusCode = 403;
return Task.CompletedTask;
}
///
/// 初始化鉴权Handler
///
/// 鉴权组合
/// http上下文
///
public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
Scheme = scheme;
Context = context;
return Task.CompletedTask;
}
///
/// 登录
///
///
///
///
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;
}
///
/// 退出
///
///
///
public Task SignOutAsync(AuthenticationProperties properties)
{
Context.Response.Cookies.Delete("AuthenticationScheme");
return Task.CompletedTask;
}
///
/// 反序列化Ticket
///
/// 字符串Ticket
///
public AuthenticationTicket Deserialize(string ticket)
{
byte[] byteTicket = Encoding.Default.GetBytes(ticket);
return TicketSerializer.Default.Deserialize(byteTicket);
}
///
/// 序列化Ticket
///
/// AuthenticationTicket
///
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("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
{
///
/// 创建Ticket中间件
///
/// IApplicationBuilder
///
public static IApplicationBuilder UseAddAuthenticationCreate(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
return app.UseMiddleware();
}
///
/// 鉴权中间件
///
/// IApplicationBuilder
///
public static IApplicationBuilder UseAddAuthentication(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
return app.UseMiddleware();
}
///
/// 授权中间件
///
/// IApplicationBuilder
///
public static IApplicationBuilder UseAddAuthorizetion(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
return app.UseMiddleware();
}
}
}
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
{
///
/// 创建鉴权Ticket
///
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
{
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
{
///
/// 鉴权
///
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
{
///
/// 授权
///
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");
}
}
}
}