asp.net core3.1 實戰開發(授權,鑑權封裝詳解)
使用方式
#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
封裝
/// <summary>
/// 自定義的handler
/// 通常會提供一個統一的認證中心,負責證書的頒發及銷燬(登入和登出),而其它服務只用來驗證證書,並用不到SingIn/SingOut。
/// </summary>
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;
}
/// <summary>
/// 認證
/// </summary>
/// <returns></returns>
public async Task<AuthenticateResult> AuthenticateAsync()
{
var cookie = Context.Request.Cookies["myCookie"];
if (string.IsNullOrEmpty(cookie))
{
return AuthenticateResult.NoResult();
}
return AuthenticateResult.Success(this.Deserialize(cookie));
}
/// <summary>
/// 沒有登入 要求 登入
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
public Task ChallengeAsync(AuthenticationProperties properties)
{
Context.Response.Redirect("/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>
/// 登入
/// </summary>
/// <param name="user"></param>
/// <param name="properties"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 退出
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
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<AuthenticationTicket>//
{
public TicketDataFormat(IDataProtector protector)
: base(TicketSerializer.Default, protector)
{
}
}
/// <summary>
/// Policy 的策略 或者是規則
/// </summary>
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();
}
}
相關文章
- asp.net core3.1 實戰開發(驗證碼的封裝和使用)ASP.NET封裝
- asp.net core3.1 實戰開發(中介軟體的詳解)ASP.NET
- ASP.NET Core策略授權和 ABP 授權ASP.NET
- 前端開發工具包-WijmoJS,部署授權詳解前端JS
- OAuth 2.0授權框架詳解OAuth框架
- Android元件化開發實戰:封裝許可權管理請求框架Android元件化封裝框架
- OAuth 2.0 授權認證詳解OAuth
- django開發之許可權管理(一)——許可權管理詳解(許可權管理原理以及方案)、不使用許可權框架的原始授權方式詳解Django框架
- 理解ASP.NET Core - 授權(Authorization)ASP.NET
- .NET Core中的鑑權授權正確方式(.NET5)
- SpringSecurity認證和授權流程詳解SpringGse
- OAuth2.0授權碼模式詳解OAuth模式
- Druid未授權訪問實戰利用UI
- API 鑑權新姿勢 – 簽名鑑權API
- AspNetCore 成長雜記(一):JWT授權鑑權之生成JWT(其二)NetCoreJWT
- AspNetCore 成長雜記(一):JWT授權鑑權之生成JWT(其一)NetCoreJWT
- ThinkJS JWT 鑑權實踐JSJWT
- Egg實現JWT鑑權JWT
- OAUTH開放授權OAuth
- 從壹開始 [ Ids4實戰 ] 之三║ 詳解授權持久化 & 使用者資料遷移持久化
- ASP.NET Core 中基於策略的授權ASP.NET
- 【ASP.NET Core】按使用者角色授權ASP.NET
- 認證鑑權與API許可權控制在微服務架構中的設計與實現:授權碼模式API微服務架構模式
- Go+gRPC-Gateway(V2) 微服務實戰,小程式登入鑑權服務(五):鑑權 gRPC-Interceptor 攔截器實戰GoRPCGateway微服務
- 認證授權方案之授權初識
- 授權|取消授權MYSQL資料庫使用者許可權MySql資料庫
- PbootCMS模板安裝與授權方法boot
- 認證授權方案之授權揭祕 (上篇)
- 【認證與授權】Spring Security的授權流程Spring
- 【ASP.NET Core學習】使用JWT認證授權ASP.NETJWT
- Asp.Net Core 企業微信靜默授權ASP.NET
- ASP.NET Core之身份認證和授權JWTASP.NETJWT
- 快速理解ASP.NET Core的認證與授權ASP.NET
- 【ASP.NET Core】按使用者等級授權ASP.NET
- ASP.NET Core 6.0 新增 JWT 認證和授權ASP.NETJWT
- Keycloak中授權的實現
- Istio安全-授權(實操三)
- 封裝、許可權修飾符、封裝的案例封裝