|
|
|
@ -3,6 +3,7 @@ using System.Security.Claims;
|
|
|
|
|
using System.Security.Policy;
|
|
|
|
|
using System.Security.Principal;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Text.Encodings.Web;
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using System.Text.Unicode;
|
|
|
|
|
using System.Threading.Tasks.Sources;
|
|
|
|
@ -10,6 +11,8 @@ using System.Threading.Tasks.Sources;
|
|
|
|
|
using Microsoft.AspNetCore;
|
|
|
|
|
using Microsoft.AspNetCore.Authentication;
|
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
using Microsoft.Extensions.Primitives;
|
|
|
|
|
|
|
|
|
|
using UAParser;
|
|
|
|
@ -17,31 +20,30 @@ using UAParser;
|
|
|
|
|
namespace AuthStudy.Authentication.Browser
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 浏览器认证 处理器
|
|
|
|
|
/// 可实现子接口 IAuthenticationRequestHandler, 以控制后续中间件是否执行.
|
|
|
|
|
/// 浏览器认证处理器:基于默认类型实现
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class BrowserAuthenticationHandler :
|
|
|
|
|
IAuthenticationHandler,
|
|
|
|
|
IAuthenticationRequestHandler,
|
|
|
|
|
IAuthenticationSignInHandler,
|
|
|
|
|
IAuthenticationSignOutHandler
|
|
|
|
|
public class BrowserAuthenticationHandler : AuthenticationHandler<BrowserAuthenticationOptions>
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
public string DefaultSchemeName = BrowserAuthenticationDefault.SchemeName;
|
|
|
|
|
|
|
|
|
|
public HttpContext? CurrentHttpContext;
|
|
|
|
|
|
|
|
|
|
public BrowserAuthenticationOptions Options;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public BrowserAuthenticationHandler(BrowserAuthenticationOptions option)
|
|
|
|
|
public BrowserAuthenticationHandler
|
|
|
|
|
(
|
|
|
|
|
IOptionsMonitor<BrowserAuthenticationOptions> options,
|
|
|
|
|
ILoggerFactory logger,
|
|
|
|
|
UrlEncoder encoder,
|
|
|
|
|
ISystemClock clock
|
|
|
|
|
) : base(options, logger, encoder, clock)
|
|
|
|
|
{
|
|
|
|
|
Options = option;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 认证
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Task<AuthenticateResult> AuthenticateAsync()
|
|
|
|
|
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
|
|
|
|
|
{
|
|
|
|
|
//认证结果
|
|
|
|
|
AuthenticateResult result;
|
|
|
|
@ -88,11 +90,11 @@ namespace AuthStudy.Authentication.Browser
|
|
|
|
|
|
|
|
|
|
//声明(身份项)
|
|
|
|
|
var browser = new Claim("Browser", clientInfo.UA.ToString()); //浏览器
|
|
|
|
|
var os = new Claim("OS", clientInfo.OS.ToString()); //操作系统
|
|
|
|
|
var device = new Claim("Device", clientInfo.Device.ToString()); //设备 //设备
|
|
|
|
|
var os = new Claim("OS", clientInfo.OS.ToString()); //操作系统
|
|
|
|
|
var device = new Claim("Device", clientInfo.Device.ToString()); //设备 //设备
|
|
|
|
|
|
|
|
|
|
//声明集合
|
|
|
|
|
var claims = new List<Claim>
|
|
|
|
|
var Claims = new List<Claim>
|
|
|
|
|
{
|
|
|
|
|
browser,
|
|
|
|
|
os,
|
|
|
|
@ -100,7 +102,7 @@ namespace AuthStudy.Authentication.Browser
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//身份:包含声明集合,是声明集合的包装类,一个身份对应多个声明
|
|
|
|
|
var claimsIdentity = new ClaimsIdentity(claims, DefaultSchemeName);
|
|
|
|
|
var claimsIdentity = new ClaimsIdentity(Claims, DefaultSchemeName);
|
|
|
|
|
|
|
|
|
|
//当事人/主角:是身份Identity的包装,对应多个身份
|
|
|
|
|
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
|
|
|
|
@ -118,78 +120,19 @@ namespace AuthStudy.Authentication.Browser
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 无认证:服务端向客户端(浏览器)发质询(要求提供一个新票据),质询体现为 http请求的响应。
|
|
|
|
|
/// 质询:服务端向客户端(浏览器)发质询(要求提供一个新票据),质询体现为 htpp请求的响应。
|
|
|
|
|
/// </summary>
|
|
|
|
|
public async Task ChallengeAsync(AuthenticationProperties? properties)
|
|
|
|
|
protected override Task HandleChallengeAsync(AuthenticationProperties? properties)
|
|
|
|
|
{
|
|
|
|
|
properties?.Parameters.Add("x-item", "无效的认证");
|
|
|
|
|
properties?.Parameters.Add("x-itme", "无效的认证");
|
|
|
|
|
|
|
|
|
|
CurrentHttpContext!.Response.StatusCode = 401;
|
|
|
|
|
if (CurrentHttpContext?.Response.Body.CanWrite ?? false)
|
|
|
|
|
{
|
|
|
|
|
var msg = Encoding.UTF8.GetBytes("认证无效");
|
|
|
|
|
await CurrentHttpContext!.Response.Body.WriteAsync(msg);
|
|
|
|
|
var msg = UTF8Encoding.UTF8.GetBytes("认证无效");
|
|
|
|
|
var t = CurrentHttpContext!.Response.Body.WriteAsync(msg);
|
|
|
|
|
}
|
|
|
|
|
CurrentHttpContext?.Items.Add("认证结束时间", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
|
|
|
|
|
//return Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 无权限:服务端向客户端(浏览器)发质询(要求提供一个新票据),质询体现为 http请求的响应。
|
|
|
|
|
/// </summary>
|
|
|
|
|
public async Task ForbidAsync(AuthenticationProperties? properties)
|
|
|
|
|
{
|
|
|
|
|
CurrentHttpContext!.Response.StatusCode = 403;
|
|
|
|
|
if (CurrentHttpContext?.Response.Body.CanWrite ?? false)
|
|
|
|
|
{
|
|
|
|
|
var msg = Encoding.UTF8.GetBytes("无权访问");
|
|
|
|
|
await CurrentHttpContext!.Response.Body.WriteAsync(msg);
|
|
|
|
|
}
|
|
|
|
|
//return Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// IAuthenticationRequestHandler
|
|
|
|
|
/// 返回true,立即反回,不执行后续中间件
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Task<bool> HandleRequestAsync()
|
|
|
|
|
{
|
|
|
|
|
return Task.FromResult(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 初始化
|
|
|
|
|
/// </summary>
|
|
|
|
|
public async Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
|
|
|
|
|
{
|
|
|
|
|
//初始化工作,传递给认证方法和授权中间件
|
|
|
|
|
CurrentHttpContext = context;
|
|
|
|
|
|
|
|
|
|
context.Items.Add("认证初始时间", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
|
|
|
|
|
|
|
|
|
|
await Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 登陆方法
|
|
|
|
|
/// 写入Cookie和Session,认证信息持久化等
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties? properties)
|
|
|
|
|
{
|
|
|
|
|
//导航到主页
|
|
|
|
|
//CurrentHttpContext?.Response.Redirect("/api/app/index");
|
|
|
|
|
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 退出方法: 反操作登陆方法
|
|
|
|
|
/// 清除Cookie和Session,删除认证信息的持久化,作废票据等
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Task SignOutAsync(AuthenticationProperties? properties)
|
|
|
|
|
{
|
|
|
|
|
//导航到登陆页
|
|
|
|
|
CurrentHttpContext?.Response.Redirect("/api/auth/login");
|
|
|
|
|
return Task.CompletedTask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -210,5 +153,6 @@ namespace AuthStudy.Authentication.Browser
|
|
|
|
|
|
|
|
|
|
return isMobile;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|