Kabul edilen cevap ( https://stackoverflow.com/a/41348219/4974715 ) "CanReadResource" bir hak talebi olarak kullanıldığından gerçekçi bir şekilde sürdürülemez veya uygun değildir (ancak esasen gerçekte bir politika, IMO olmalıdır). Yanıttaki yaklaşım, kullanıldığı şekilde uygun değildir, çünkü bir eylem yöntemi birçok farklı talep kurulumu gerektiriyorsa, o zaman bu cevapla tekrar tekrar böyle bir şey yazmanız gerekir ...
[ClaimRequirement(MyClaimTypes.Permission, "CanReadResource")]
[ClaimRequirement(MyClaimTypes.AnotherPermision, "AnotherClaimVaue")]
//and etc. on a single action.
Bunun ne kadar kodlama alacağını hayal edin. İdeal olarak, "CanReadResource" bir kullanıcının bir kaynağı okuyabilip okuyamayacağını belirlemek için birçok iddia kullanan bir politika olması gerekir.
Yaptığım şey, bir numaralandırma olarak politikalarımı oluşturmak ve sonra döngü ve böylece gibi gereksinimleri ayarlamak ...
services.AddAuthorization(authorizationOptions =>
{
foreach (var policyString in Enum.GetNames(typeof(Enumerations.Security.Policy)))
{
authorizationOptions.AddPolicy(
policyString,
authorizationPolicyBuilder => authorizationPolicyBuilder.Requirements.Add(new DefaultAuthorizationRequirement((Enumerations.Security.Policy)Enum.Parse(typeof(Enumerations.Security.Policy), policyWrtString), DateTime.UtcNow)));
/* Note that thisn does not stop you from
configuring policies directly against a username, claims, roles, etc. You can do the usual.
*/
}
});
DefaultAuthorizationRequirement sınıfı ...
public class DefaultAuthorizationRequirement : IAuthorizationRequirement
{
public Enumerations.Security.Policy Policy {get; set;} //This is a mere enumeration whose code is not shown.
public DateTime DateTimeOfSetup {get; set;} //Just in case you have to know when the app started up. And you may want to log out a user if their profile was modified after this date-time, etc.
}
public class DefaultAuthorizationHandler : AuthorizationHandler<DefaultAuthorizationRequirement>
{
private IAServiceToUse _aServiceToUse;
public DefaultAuthorizationHandler(
IAServiceToUse aServiceToUse
)
{
_aServiceToUse = aServiceToUse;
}
protected async override Task HandleRequirementAsync(AuthorizationHandlerContext context, DefaultAuthorizationRequirement requirement)
{
/*Here, you can quickly check a data source or Web API or etc.
to know the latest date-time of the user's profile modification...
*/
if (_aServiceToUse.GetDateTimeOfLatestUserProfileModication > requirement.DateTimeOfSetup)
{
context.Fail(); /*Because any modifications to user information,
e.g. if the user used another browser or if by Admin modification,
the claims of the user in this session cannot be guaranteed to be reliable.
*/
return;
}
bool shouldSucceed = false; //This should first be false, because context.Succeed(...) has to only be called if the requirement specifically succeeds.
bool shouldFail = false; /*This should first be false, because context.Fail()
doesn't have to be called if there's no security breach.
*/
// You can do anything.
await doAnythingAsync();
/*You can get the user's claims...
ALSO, note that if you have a way to priorly map users or users with certain claims
to particular policies, add those policies as claims of the user for the sake of ease.
BUT policies that require dynamic code (e.g. checking for age range) would have to be
coded in the switch-case below to determine stuff.
*/
var claims = context.User.Claims;
// You can, of course, get the policy that was hit...
var policy = requirement.Policy
//You can use a switch case to determine what policy to deal with here...
switch (policy)
{
case Enumerations.Security.Policy.CanReadResource:
/*Do stuff with the claims and change the
value of shouldSucceed and/or shouldFail.
*/
break;
case Enumerations.Security.Policy.AnotherPolicy:
/*Do stuff with the claims and change the
value of shouldSucceed and/or shouldFail.
*/
break;
// Other policies too.
default:
throw new NotImplementedException();
}
/* Note that the following conditions are
so because failure and success in a requirement handler
are not mutually exclusive. They demand certainty.
*/
if (shouldFail)
{
context.Fail(); /*Check the docs on this method to
see its implications.
*/
}
if (shouldSucceed)
{
context.Succeed(requirement);
}
}
}
Yukarıdaki kodun, bir kullanıcının veri deponuzdaki bir politika ile önceden eşlenmesini de sağlayabileceğini unutmayın. Bu nedenle, kullanıcı için hak talepleri oluştururken, temel olarak doğrudan veya dolaylı olarak kullanıcıya önceden eşlenmiş politikaları alırsınız (örneğin, kullanıcının belirli bir hak talebi değeri olduğu ve bu hak bedelinin tanımlanmış ve bir politika ile eşlenmiş olması gibi) bu hak talebi değerine sahip kullanıcılar için otomatik eşleme sağladığını) ve politikaları hak talebi olarak listeleyerek yetkilendirme işleyicisinde, kullanıcının taleplerinin gereksinim içerip içermediğini kontrol edebilirsiniz. iddialar. Bu, bir politika gereksinimini karşılamanın statik bir yoludur, örneğin "Ad" gereksinimi doğada oldukça statiktir. Yani,
[Authorize(Policy = nameof(Enumerations.Security.Policy.ViewRecord))]
Dinamik bir gereksinim yaş aralığını vb. Denetlemeyle ilgili olabilir ve bu gereksinimleri kullanan politikalar kullanıcılarla önceden eşleştirilemez.
Dinamik politika talepleri kontrolünün bir örneği (örneğin, bir kullanıcının 18 yaşından büyük olup olmadığını kontrol etmek için) zaten @blowdart ( https://stackoverflow.com/a/31465227/4974715 ) tarafından verilen yanıtta bulunmaktadır .
Not: Bunu telefonuma yazdım. Herhangi bir yazım hatası ve biçimlendirme eksikliğini affedin.