2016-04-06 12 views
0

ASP.NET Kimliği ile bir ASP.NET Çekirdeğinde Angular kullanıyorum. Bir kullanıcı kendi notları sadece erişebilir daha doğrulanırsaBaşka bir kullanıcıdan veri görmek için bir kullanıcının erişimini engelleyin

:

Bu kadar API erişimi kısıtlamak istiyorum aşağıdaki kontrolör eylemi

[HttpGet("users/{userId:int:min(1)}/notes"), Authorize] 
public async Task<IActionResult> GetNotesBy(userId) { 

    var data = _service.getNotesBy(userId); 
    return Ok(data); 

} // GetNotesBy 

var. ID = X kimliğine sahip bir kullanıcının kimliğini ID = Y olan bir kullanıcının notlarına erişmesini önlemek istiyorum. Bu durumda bir kullanıcıyı nasıl engelleyebilirim?

+0

'Identiy' işlevini kullanabilir ve userId öğesini URL'de –

+0

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ı? –

+1

Evet, bunu yapmak için bir filtreyi veya yetkilendirme özniteliğini kullanabilirsiniz. –

cevap

3

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.

+0

Sadece meraktan ötürü, kaynakların sadece bir kullanıcı için erişimi olan değerleri döndürmek için 'IEnumerable 'olduğu bir durumu nasıl ele alırsınız? Kaynak tabanlı yaklaşımla bile mümkün mü? Kullanıcının iki veya daha fazla gruba ait olduğunu ve GetAllNotesForuser (userId) 'yi aldığını varsayalım mı? Kullanıcıların rolünü belirlemek için depoda bir çeşit katılımda bulunma veya izin alması veya daha iyi yaklaşımlar var mı? SOLID prensipleri ile çatışmanın bir parça içerisine girdiğini kontrol etmek için – Tseng

+0

numaralı depoda kullanıcıyı depoya geçirirdim ve katıyla ilgilenmezdim – blowdart

+0

Blowdart Bence bu kadar basit olmayabilir. DTO'ları kullanırken kaynak nedir? Varlıklar var mı? Birçok varlığa sahip olduğunuzda, hepsinin yetkilendirmesini kontrol edecek misiniz? Kaynak Yetkilendirmesi, DTO'lar ve Veri Yolu ile gerçek bir durum senaryosu yayınladım: http://stackoverflow.com/questions/36622749/resource-authorization-with-dtos-and-bus-scenario. –

İlgili konular