使用方式
#region 设置自己的schema的handler
services.AddAuthenticationCore(options => options.AddScheme<MyHandler>("myScheme", "demo myScheme"));
#endregion
#region 支持 policy 认证授权的服务
// 指定通过策略验证的策略列
services.AddSingleton<IAuthorizationHandler, AdvancedRequirement>();
services.AddAuthorization(options =>
{
//AdvancedRequirement可以理解为一个别名
options.AddPolicy("AdvancedRequirement", policy =>
{
policy.AddRequirements(new NameAuthorizationRequirement("1"));
});
}).AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.LoginPath = new PathString("/Fourth/Login");
options.ClaimsIssuer = "Cookie";
});
#endregion
#region Schame 验证
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;// "Richard";//
})
.AddCookie(options =>
{
options.LoginPath = new PathString("/Fourth/Login");// 这里指定如果验证不通过就跳转到这个页面中去
options.ClaimsIssuer = "Cookie";
});
#endregion
#region 认证授权基本模型
//// 登录
app.Map("/login", builder => builder.Use(next =>
{
return async (context) =>
{
var claimIdentity = new ClaimsIdentity(); // 可以把这个ClaimsIdentity理解成一个身份证
claimIdentity.AddClaim(new Claim(ClaimTypes.Name, "XT")); // 用户信息的载体
// Scheme 可以理解为 跟身份证对应的一个标识
await context.SignInAsync("myScheme", new ClaimsPrincipal(claimIdentity));
await context.Response.WriteAsync($"Hello, ASP.NET Core! {context.User.Identity.Name} Login");
};
}));
// 退出
app.Map("/logout", builder => builder.Use(next =>
{
return async (context) =>
{
await context.SignOutAsync("myScheme");
};
}));
app.Use(next => //认证 认识身份证
{
return async (context) =>
{
var result = await context.AuthenticateAsync("myScheme");
if (result?.Principal != null)
{
context.User = result.Principal;
await next(context);
}
else
{
await context.ChallengeAsync("myScheme");
}
};
});
// 授权 身份证有什么权限
app.Use(async (context, next) =>
{
var user = context.User;
if (user.Identity.Name.Equals("XT"))//user?.Identity?.IsAuthenticated这里没有授权检测 只检查下名称
{
await next();
}
else
{
await context.ForbidAsync("myScheme");
}
//if (user?.Identity?.IsAuthenticated ?? false)
//{
// if (user.Identity.Name != "jim") await context.ForbidAsync("eScheme");
// else await next();
//}
//else
//{
// await context.ChallengeAsync("eScheme");
//}
});
// 访问受保护资源
app.Map("/resource", builder => builder.Run(async (context) =>
{
await context.Response.WriteAsync($"Hello, ASP.NET Core! {context.User.Identity.Name}");
}));
app.Run(async (HttpContext context) =>
{
await context.Response.WriteAsync("Hello World,success!");
});
#endregion
封装
///
/// 自定义的handler
/// 通常会提供一个统一的认证中心,负责证书的颁发及销毁(登入和登出),而其它服务只用来验证证书,并用不到SingIn/SingOut。
///
public class MyHandler : IAuthenticationHandler, IAuthenticationSignInHandler, IAuthenticationSignOutHandler
{
public AuthenticationScheme Scheme { get; private set; }
protected HttpContext Context { get; private set; }
public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
Scheme = scheme;
Context = context;
return Task.CompletedTask;
}
///
/// 认证
///
///
public async Task<AuthenticateResult> AuthenticateAsync()
{
var cookie = Context.Request.Cookies["myCookie"];
if (string.IsNullOrEmpty(cookie))
{
return AuthenticateResult.NoResult();
}
return AuthenticateResult.Success(this.Deserialize(cookie));
}
///
/// 没有登录 要求 登录
///
///
///
public Task ChallengeAsync(AuthenticationProperties properties)
{
Context.Response.Redirect("/login");
return Task.CompletedTask;
}
///
/// 没权限
///
///
///
public Task ForbidAsync(AuthenticationProperties properties)
{
Context.Response.StatusCode = 403;
return Task.CompletedTask;
}
///
/// 登录
///
///
///
///
public Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties properties)
{
var ticket = new AuthenticationTicket(user, properties, Scheme.Name);
Context.Response.Cookies.Append("myCookie", this.Serialize(ticket));
return Task.CompletedTask;
}
///
/// 退出
///
///
///
public Task SignOutAsync(AuthenticationProperties properties)
{
Context.Response.Cookies.Delete("myCookie");
return Task.CompletedTask;
}
private AuthenticationTicket Deserialize(string content)
{
byte[] byteTicket = System.Text.Encoding.Default.GetBytes(content);
return TicketSerializer.Default.Deserialize(byteTicket);
}
private string Serialize(AuthenticationTicket ticket)
{
//需要引入 Microsoft.AspNetCore.Authentication
byte[] byteTicket = TicketSerializer.Default.Serialize(ticket);
return Encoding.Default.GetString(byteTicket);
}
}
public class TicketDataFormat : SecureDataFormat<AuthenticationTicket>// IDataSerializer//
{
public TicketDataFormat(IDataProtector protector)
: base(TicketSerializer.Default, protector)
{
}
}
///
/// Policy 的策略 或者是规则
///
public class AdvancedRequirement : AuthorizationHandler<NameAuthorizationRequirement>, IAuthorizationRequirement
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, NameAuthorizationRequirement requirement)
{
// 这里可以把用户信息获取到以后通过数据库进行验证
// 这里就可以做一个规则验证
// 也可以通过配置文件来验证
if (context.User != null && context.User.HasClaim(c => c.Type == ClaimTypes.Sid))
{
string sid = context.User.FindFirst(c => c.Type == ClaimTypes.Sid).Value;
if (!sid.Equals(requirement.RequiredName))
{
context.Succeed(requirement);
}
}
return Task.CompletedTask;
}
}
public class RoleAuthorizationRequirement : AuthorizationHandler<RoleAuthorizationRequirement>, IAuthorizationRequirement
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleAuthorizationRequirement requirement)
{
throw new NotImplementedException();
}
}