Program.cs
#region 授權(quán)
builder.Services.AddAuthorization(option =>
{
//添加自定義授權(quán)策略
option.AddPolicy("MyPolicy",p => p.RequireClaim(ClaimTypes.NameIdentifier,"1"));
});
#endregion
TestController.cs 應(yīng)用自定義授權(quán)策略
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
[Authorize("MyPolicy")]
[HttpGet]
public async Task<string> Get()
{
return await Task.FromResult(DateTime.Now.ToString());
}
}
TokenAuthenticationHandler.cs
public Task<AuthenticateResult> AuthenticateAsync()
{
string token = _context.Request.Headers["Authorization"];
if (token == "test")
{
ClaimsIdentity identity = new ClaimsIdentity("Ctm");
identity.AddClaims(new List<Claim>(){
new Claim(ClaimTypes.Name,"admin"),
new Claim(ClaimTypes.NameIdentifier,"6")
});
var claimsPrincipal = new ClaimsPrincipal(identity);
return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, null, _scheme.Name)));
}
return Task.FromResult(AuthenticateResult.Fail("token錯(cuò)誤,請(qǐng)重新登錄"));
}
/// <summary>
/// 沒(méi)有權(quán)限訪問(wèn)
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public Task ForbidAsync(AuthenticationProperties? properties)
{
_context.Response.StatusCode = 403;
return Task.CompletedTask;
}
此處鑒權(quán)給的值是6,授權(quán)用的1,嘗試訪問(wèn)
重要概念
基于策略的授權(quán)中有一個(gè)很重要的概念是Requirements,每一個(gè)Requirement都代表一個(gè)授權(quán)條件。
Requirement需要繼承接口IAuthorizationRequirement。
已經(jīng)內(nèi)置了一些常用的實(shí)現(xiàn):
AssertionRequirement :使用最原始的斷言形式來(lái)聲明授權(quán)策略。
DenyAnonymousAuthorizationRequirement :用于表示禁止匿名用戶訪問(wèn)的授權(quán)策略,并在AuthorizationOptions中將其設(shè)置為默認(rèn)策略。
ClaimsAuthorizationRequirement :用于表示判斷Cliams中是否包含預(yù)期的Claims的授權(quán)策略。
RolesAuthorizationRequirement :用于表示使用ClaimsPrincipal.IsInRole來(lái)判斷是否包含預(yù)期的Role的授權(quán)策略。
NameAuthorizationRequirement:用于表示使用ClaimsPrincipal.Identities.Name來(lái)判斷是否包含預(yù)期的Name的授權(quán)策略。
OperationAuthorizationRequirement:用于表示基于操作的授權(quán)策略。
當(dāng)內(nèi)置的Requirement不能滿足需求時(shí),可以定義自己的Requirement.文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-772384.html
自定義Requirement
builder.Services.AddAuthorization(option =>
{
option.AddPolicy("MyPolicy",p => p.Requirements.Add(new MyAuthorizationHandler("1")));
});
MyAuthorizationHandler.cs
public class MyAuthorizationHandler : AuthorizationHandler<MyAuthorizationHandler>, IAuthorizationRequirement
{
private readonly string _userId;
public MyAuthorizationHandler(string userId)
{
_userId = userId;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyAuthorizationHandler requirement)
{
if (context.User.HasClaim(c => c.Type == ClaimTypes.NameIdentifier)
&& context.User.Claims.FirstOrDefault(c => c.Type.Equals(ClaimTypes.NameIdentifier)).Value == _userId)
{
context.Succeed(requirement);
}
else
{
context.Fail();
}
return Task.CompletedTask;
}
}
多授權(quán)方案
builder.Services.AddAuthorization(option =>
{
option.AddPolicy("MyPolicy",p => p.Requirements.Add(new MyAuthorizationHandler("1")));
option.AddPolicy("MyPolicy1", p => p.Requirements.Add(new MyAuthorizationHandler1("admin")));
});
MyAuthorizationHandler1.cs
public class MyAuthorizationHandler1 : AuthorizationHandler<MyAuthorizationHandler1>, IAuthorizationRequirement
{
private readonly string _userName;
public MyAuthorizationHandler1(string userName)
{
_userName = userName;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, MyAuthorizationHandler1 requirement)
{
if (context.User.HasClaim(c => c.Type == ClaimTypes.Name)
&& context.User.Claims.FirstOrDefault(c => c.Type.Equals(ClaimTypes.Name)).Value == _userName)
{
context.Succeed(requirement);
}
else
{
context.Fail();
}
return Task.CompletedTask;
}
}
TestController.cs
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
[Authorize(Policy = "MyPolicy")]
[Authorize(Policy = "MyPolicy1")]
[HttpGet]
public async Task<string> Get()
{
return await Task.FromResult(DateTime.Now.ToString());
}
}
鑒權(quán)方案 TokenAuthenticationHandler.cs
public class TokenAuthenticationHandler : IAuthenticationHandler
{
private AuthenticationScheme _scheme;
private HttpContext _context;
/// <summary>
/// 鑒權(quán)初始化
/// </summary>
/// <param name="scheme">鑒權(quán)架構(gòu)名稱</param>
/// <param name="context">HttpContext</param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
_scheme = scheme;
_context = context;
return Task.CompletedTask;
}
public Task<AuthenticateResult> AuthenticateAsync()
{
string token = _context.Request.Headers["Authorization"];
if (token == "test")
{
ClaimsIdentity identity = new ClaimsIdentity("Ctm");
identity.AddClaims(new List<Claim>(){
new Claim(ClaimTypes.Name,"admin"),
new Claim(ClaimTypes.NameIdentifier,"1")
});
var claimsPrincipal = new ClaimsPrincipal(identity);
return Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, null, _scheme.Name)));
}
return Task.FromResult(AuthenticateResult.Fail("token錯(cuò)誤,請(qǐng)重新登錄"));
}
/// <summary>
/// 未登錄
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public Task ChallengeAsync(AuthenticationProperties? properties)
{
_context.Response.Redirect("/api/Login/NoLogin");
return Task.CompletedTask;
}
/// <summary>
/// 沒(méi)有權(quán)限訪問(wèn)
/// </summary>
/// <param name="properties"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public Task ForbidAsync(AuthenticationProperties? properties)
{
_context.Response.StatusCode = 403;
return Task.CompletedTask;
}
}
多授權(quán)方案,每個(gè)授權(quán)策略都需要通過(guò)
那么也可以使用多鑒權(quán)架構(gòu),Cookie可用于web瀏覽器,token用于終端API調(diào)用
改造效果:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-772384.html
多鑒權(quán)方案
Program.cs
//注冊(cè)鑒權(quán)架構(gòu)
#region Cookie
builder.Services.AddAuthentication("Cookies").AddCookie(o =>{
o.LoginPath = "/api/Login/NoLogin";
});
#region 自定義Token驗(yàn)證
builder.Services.AddAuthentication(option =>
{
//把自定義的鑒權(quán)方案添加到鑒權(quán)架構(gòu)中
option.AddScheme<TokenAuthenticationHandler>("token", "myToken");
option.DefaultAuthenticateScheme = "token";
option.DefaultChallengeScheme = "token";
option.DefaultForbidScheme = "token";
});
#endregion
#endregion
#region 授權(quán)
// builder.Services.AddAuthorization(option =>
// {
// option.AddPolicy("MyPolicy",p => p.RequireClaim(ClaimTypes.NameIdentifier,"1"));
// });
builder.Services.AddAuthorization(option =>
{
option.AddPolicy("MyPolicy",p => p.Requirements.Add(new MyAuthorizationHandler("1")));
// option.AddPolicy("MyPolicy1", p => p.Requirements.Add(new MyAuthorizationHandler1("admin")));
});
#endregion
TestController.cs
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
[Authorize(Policy = "MyPolicy",AuthenticationSchemes = $"token,Cookies")]
[HttpGet]
public async Task<string> Get()
{
return await Task.FromResult(DateTime.Now.ToString());
}
}
授權(quán)綁定鑒權(quán)
//注冊(cè)鑒權(quán)架構(gòu)
#region Cookie
builder.Services.AddAuthentication("Cookies").AddCookie(o =>{
o.LoginPath = "/api/Login/NoLogin";
});
#region 自定義Token驗(yàn)證
builder.Services.AddAuthentication(option =>
{
//把自定義的鑒權(quán)方案添加到鑒權(quán)架構(gòu)中
option.AddScheme<TokenAuthenticationHandler>("token", "myToken");
//option.DefaultAuthenticateScheme = "token";
option.DefaultChallengeScheme = "token";
option.DefaultForbidScheme = "token";
});
#endregion
#endregion
builder.Services.AddAuthorization(option =>
{
option.AddPolicy("MyPolicy",p =>p.AddAuthenticationSchemes("token").Requirements.Add(new MyAuthorizationHandler("1")));
option.AddPolicy("MyPolicy1", p =>p.AddAuthenticationSchemes("Cookies").Requirements.Add(new MyAuthorizationHandler1("admin")));
});
到了這里,關(guān)于ASP.NET Core 鑒權(quán)授權(quán)三(添加自定義授權(quán)策略)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!