Bu, kaynak tabanlı yetkilendirmenin amaçlandığı şeydir. Kaynak tabanlı yetkilendirme, asıl kaynağı gerektirdiği için, kontrol cihazınızın içinde zorunlu olarak gerçekleşmesi gerekir.
Aşağıdakiler ASP.NET Core RC1 içindir.
Yani, getNotesBy öğenizin bir Notes
sınıfını döndürdüğünü ve birkaç işleminiz olduğunu varsayalım, oku, yaz, güncelleştir, sil.
İlk önce işlemleri tanımlamamız gerekiyor. Microsoft.AspNet.Authorization.Infrastructure
, OperationAuthorizationRequirement
'da uygun bir temel sınıf var. Yani böyle bir şey yapardık.
public static class Operations
{
public static OperationAuthorizationRequirement Create =
new OperationAuthorizationRequirement { Name = "Create" };
public static OperationAuthorizationRequirement Read =
new OperationAuthorizationRequirement { Name = "Read" };
public static OperationAuthorizationRequirement Update =
new OperationAuthorizationRequirement { Name = "Update" };
public static OperationAuthorizationRequirement Delete =
new OperationAuthorizationRequirement { Name = "Delete" };
}
Artık işlemlerimiz var, yetkilendirmeyi nasıl ele aldığımızı düşünüyoruz. Geçerli kullanıcı notlara sahipse veya geçerli kullanıcı bir yönetici ise işlemlerin başarılı olabilmesi için iki yol vardır. Bu, tek bir gereksinim/işlem için iki işleyiciye eşittir.
Yönetici olan kolay, böyle bir şey olurdu;
public class AdminAuthorizationHander :
AuthorizationHandler<OperationAuthorizationRequirement, Notes>
{
protected override void Handle(AuthorizationContext context,
OperationAuthorizationRequirement requirement,
Document resource)
{
var isSuperUser = context.User.FindFirst(c => c.Type == "Superuser" &&
c.Value == "True");
if (isSuperUser != null)
{
context.Succeed(requirement);
return;
}
}
}
Burada True değeri olan bir Superuser talebi arıyoruz. Eğer mevcutsa, şartı yerine getiririz. OperationAuthorizationRequirement ve bir kaynak olan Notes sınıfını kullandığımız yöntem imzasından görebilirsiniz. Bu işleyici kendini tek bir operasyonla sınırlamaz, yöneticilerin her operasyona hakları vardır.
Şimdi gerçek kullanıcıyı arayan işleyiciyi yazabiliriz.
public class NotesAuthorizationHandler :
AuthorizationHandler<OperationAuthorizationRequirement, Notes>
{
protected override void Handle(AuthorizationContext context,
OperationAuthorizationRequirement requirement,
Notes resource)
{
if (context.User.Name == resource.Owner)
{
context.Succeed(requirement);
}
}
}
Burada tüm kaynakların çalışacak bir şey yazma ve geçerli kullanıcı adını karşı kaynakta bir Sahibi özelliği denetler edilir.
Şimdi tek bir gereksinim için OperationAuthorizationRequirement
iki işleyicimiz var.
Şimdi bizim işleyicileri kaydetmemiz gerekiyor. startup.cs
'da, ConfigureServices()
yöntemindeki DI'deki işleyicileri kaydedersiniz. services.AddAuthorization()
numaralı çağrıdan sonra, işleyicilerinizi DI'ye koymanız gerekir. Bunu böyle yaparsın;
services.AddSingleton<IAuthorizationHandler, AdminAuthorizationHandler>();
services.AddSingleton<IAuthorizationHandler, NotesAuthorizationHandler>();
Sen bir DbContext
gibi şeyler alıyorsanız istediğiniz gibi Singleton
den kapsamını ayarlayabilirsiniz.
Son olarak, bunu hemen hemen aramaya hazırız, ancak önce denetleyici kurucunuzu IAuthorizationService
örneğini almak için değiştirmeniz gerekir. Bunu aldıktan sonra, AuthorizeAsync()
numaralı telefonu arayabilir ve gidersiniz.
[Authorize]
public class NotesController : Controller
{
IAuthorizationService _authorizationService;
public NotesController(IAuthorizationService authorizationService)
{
_authorizationService = authorizationService;
}
[HttpGet("users/{userId:int:min(1)}/notes"), Authorize]
public async Task<IActionResult> GetNotesBy(userId)
{
var resource = _service.getNotesBy(userId);
if (await authorizationService.AuthorizeAsync(User, resource, Operations.Read))
{
return Ok(data);
}
return new ChallengeResult();
}
}
Yaptığınız şey kaynağınızı almak ve ardından geçerli kullanıcıyı buna ve işleme karşı yetkilendirmektir. Bu olduğunda, bu kaynak ve işlemle başa çıkabilecek tüm işleyiciler aranacaktır. Birden fazla işleyici olduğundan, herhangi biri başarılı olabilir ve erişime izin verebilir.
'Identiy' işlevini kullanabilir ve userId öğesini URL'de –
URL'sine göndermek yerine "HttpContext.User" adresinden alabilirsiniz. Bu bir fikir ancak bu API'nin daha genel olmasını istiyorum. tüm kullanıcılara erişimi olan bir yönetici. Fikrim, kullanıcının Rol yöneticisi olup olmadığını kontrol etmektir. Eğer evet değilse o zaman erişim verin, o zaman userId'nin HttpContext.User'den Kimlik Kullanıcı Kimliği'ne eşit olup olmadığını kontrol edin. Bu mantıklı mı? –
Evet, bunu yapmak için bir filtreyi veya yetkilendirme özniteliğini kullanabilirsiniz. –