ASP.NET Web API'sinde Kimlik Doğrulaması ve Yetkilendirme
tarafından Rick Anderson
Bir web API'sini oluşturdunuz, ancak şimdi buna erişimi denetlemek istiyorsunuz. Bu makale serisinde, yetkisiz kullanıcıların web API'sini güvenli hale getirmek için bazı seçenekleri inceleyeceğiz. Bu seride hem kimlik doğrulaması hem de yetkilendirme ele alınacaktır.
- Kimlik doğrulaması , kullanıcının kimliğini bilmektir. Örneğin, Alice kullanıcı adı ve parolası ile oturum açar ve sunucu, Alice'in kimliğini doğrulamak için parolayı kullanır.
- Yetkilendirme , kullanıcının eylem gerçekleştirmesine izin verilip verilmeyeceğine karar vermektir. Örneğin, Alice'in kaynak alma izni vardır ancak kaynak oluşturma izni yoktur.
Serinin ilk makalesi, ASP.NET Web API'sinde kimlik doğrulaması ve yetkilendirmeye genel bir genel bakış sağlar. Diğer konularda Web API'sinde yaygın kimlik doğrulama senaryoları açıklanmaktadır.
Not
Bu seriyi inceleyen ve değerli geri bildirimler sağlayan kişilere teşekkür ederiz: Rick Anderson, Levi Broderick, Barry Dorrans, Tom Dykstra, Hongmei Ge, David Matson, Daniel Roth, Tim Teebken.
Kimlik Doğrulaması
Web API'sinde kimlik doğrulamasının konakta gerçekleştiği varsayılır. Web barındırma için ana bilgisayar, kimlik doğrulaması için HTTP modülleri kullanan IIS'dir. Projenizi IIS veya ASP.NET yerleşik kimlik doğrulama modüllerinden herhangi birini kullanacak şekilde yapılandırabilir veya özel kimlik doğrulaması gerçekleştirmek için kendi HTTP modülünüzü yazabilirsiniz.
Konak kullanıcının kimliğini doğruladığında, kodun altında çalıştığı güvenlik bağlamını temsil eden bir IPrincipal nesnesi olan bir sorumlu oluşturur. Ana bilgisayar , Thread.CurrentPrincipal öğesini ayarlayarak sorumluyu geçerli iş parçacığına ekler. Sorumlu, kullanıcı hakkında bilgi içeren ilişkili bir Identity nesnesi içerir. Kullanıcının kimliği doğrulanmışsa Identity.IsAuthenticated özelliği true değerini döndürür. Anonim istekler için IsAuthenticatedfalse döndürür. Sorumlular hakkında daha fazla bilgi için bkz . Rol Tabanlı Güvenlik.
Kimlik Doğrulaması için HTTP İleti İşleyicileri
Kimlik doğrulaması için konağı kullanmak yerine, kimlik doğrulama mantığını bir HTTP ileti işleyicisine yerleştirebilirsiniz. Bu durumda, ileti işleyiciSI HTTP isteğini inceler ve sorumluyu ayarlar.
Kimlik doğrulaması için ne zaman ileti işleyicileri kullanmalısınız? İşte bazı dezavantajlar:
- HTTP modülü, ASP.NET işlem hattından geçen tüm istekleri görür. İleti işleyicisi yalnızca Web API'sine yönlendirilen istekleri görür.
- Belirli bir yola kimlik doğrulama şeması uygulamanıza olanak tanıyan yol başına ileti işleyicileri ayarlayabilirsiniz.
- HTTP modülleri IIS'ye özeldir. İleti işleyicileri konak bağımsızdır, bu nedenle hem web barındırma hem de kendi kendine barındırma ile kullanılabilirler.
- HTTP modülleri IIS günlüğe kaydetme, denetleme vb. işlemlerine katılır.
- HTTP modülleri daha önce işlem hattında çalışır. Kimlik doğrulamasını bir ileti işleyicisinde işlerseniz, işleyici çalıştırılıncaya kadar sorumlu ayarlanmaz. Ayrıca, yanıt ileti işleyiciden ayrıldığında sorumlu önceki sorumluya geri döner.
Genel olarak, kendi kendine barındırmayı desteklemeniz gerekmiyorsa HTTP modülü daha iyi bir seçenektir. Kendi kendine barındırmayı desteklemeniz gerekiyorsa bir ileti işleyicisi düşünün.
Sorumluyu Ayarlama
Uygulamanız herhangi bir özel kimlik doğrulama mantığı gerçekleştiriyorsa, sorumluyu iki yerde ayarlamanız gerekir:
- Thread.CurrentPrincipal. Bu özellik, .NET'te iş parçacığının sorumlusunu ayarlamanın standart yoludur.
- HttpContext.Current.User. Bu özellik ASP.NET özgüdür.
Aşağıdaki kodda sorumlunun nasıl ayarlanacağı gösterilmektedir:
private void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
Web barındırma için, sorumluyu her iki yerde de ayarlamanız gerekir; aksi takdirde güvenlik bağlamı tutarsız hale gelebilir. Ancak kendi kendine barındırma için HttpContext.Current null değeridir. Bu nedenle kodunuzun host-agnostic olduğundan emin olmak için, gösterildiği gibi HttpContext.Current'a atamadan önce null değerini denetleyin.
Yetkilendirme
Yetkilendirme daha sonra işlem hattında, denetleyiciye daha yakın bir tarihte gerçekleşir. Bu, kaynaklara erişim sağlarken daha ayrıntılı seçimler yapmanıza olanak tanır.
- Yetkilendirme filtreleri denetleyici eyleminden önce çalışır. İstek yetkilendirilmediyse, filtre bir hata yanıtı döndürür ve eylem çağrılmaz.
- Denetleyici eyleminde, Geçerli sorumluyu ApiController.User özelliğinden alabilirsiniz. Örneğin, kaynak listesini kullanıcı adına göre filtreleyebilirsiniz ve yalnızca o kullanıcıya ait olan kaynakları döndürebilirsiniz.
[Authorize] Özniteliğini Kullanma
Web API'si, AuthorizeAttribute adlı yerleşik bir yetkilendirme filtresi sağlar. Bu filtre, kullanıcının kimliğinin doğrulanıp doğrulanmamış olduğunu denetler. Aksi takdirde, eylemi çağırmadan HTTP durum kodu 401 (Yetkisiz) döndürür.
Filtreyi genel olarak, denetleyici düzeyinde veya tek tek eylemler düzeyinde uygulayabilirsiniz.
Genel olarak: Her Web API denetleyicisinin erişimini kısıtlamak için , AuthorizeAttribute filtresini genel filtre listesine ekleyin:
public static void Register(HttpConfiguration config)
{
config.Filters.Add(new AuthorizeAttribute());
}
Denetleyici: Belirli bir denetleyicinin erişimini kısıtlamak için filtreyi denetleyiciye öznitelik olarak ekleyin:
// Require authorization for all actions on the controller.
[Authorize]
public class ValuesController : ApiController
{
public HttpResponseMessage Get(int id) { ... }
public HttpResponseMessage Post() { ... }
}
Eylem: Belirli eylemlere erişimi kısıtlamak için özniteliğini eylem yöntemine ekleyin:
public class ValuesController : ApiController
{
public HttpResponseMessage Get() { ... }
// Require authorization for a specific action.
[Authorize]
public HttpResponseMessage Post() { ... }
}
Alternatif olarak, özniteliğini kullanarak denetleyiciyi kısıtlayabilir ve ardından belirli eylemlere anonim erişime [AllowAnonymous]
izin vekleyebilirsiniz. Aşağıdaki örnekte Post
yöntemi kısıtlanmıştır, ancak Get
yöntemi anonim erişime izin verir.
[Authorize]
public class ValuesController : ApiController
{
[AllowAnonymous]
public HttpResponseMessage Get() { ... }
public HttpResponseMessage Post() { ... }
}
Önceki örneklerde, filtre kimliği doğrulanmış herhangi bir kullanıcının kısıtlı yöntemlere erişmesine izin verir; yalnızca anonim kullanıcılar dışarıda tutulur. Ayrıca erişimi belirli kullanıcılarla veya belirli rollerdeki kullanıcılarla sınırlayabilirsiniz:
// Restrict by user:
[Authorize(Users="Alice,Bob")]
public class ValuesController : ApiController
{
}
// Restrict by role:
[Authorize(Roles="Administrators")]
public class ValuesController : ApiController
{
}
Not
Web API denetleyicileri için AuthorizeAttribute filtresi System.Web.Http ad alanında bulunur. System.Web.Mvc ad alanında, Web API denetleyicileriyle uyumlu olmayan MVC denetleyicileri için de benzer bir filtre vardır.
Özel Yetkilendirme Filtreleri
Özel yetkilendirme filtresi yazmak için aşağıdaki türlerden birinden türetin:
- AuthorizeAttribute. Geçerli kullanıcıya ve kullanıcının rollerine göre yetkilendirme mantığı gerçekleştirmek için bu sınıfı genişletin.
- AuthorizationFilterAttribute. Geçerli kullanıcı veya rolü temel almaması gereken zaman uyumlu yetkilendirme mantığı gerçekleştirmek için bu sınıfı genişletin.
- IAuthorizationFilter. Zaman uyumsuz yetkilendirme mantığı gerçekleştirmek için bu arabirimi uygulayın; örneğin, yetkilendirme mantığınız zaman uyumsuz G/Ç veya ağ çağrıları yaparsa. (Yetkilendirme mantığınız CPU'ya bağlıysa AuthorizationFilterAttribute'tan türetmek daha kolaydır, çünkü zaman uyumsuz bir yöntem yazmanız gerekmez.)
Aşağıdaki diyagramda AuthorizeAttribute sınıfının sınıf hiyerarşisi gösterilmektedir.
Authorize Attribute sınıfı için sınıf hiyerarşisinin diyagramı. Yetkilendirme Özniteliği en altta, Yetkilendirme Filtresi Özniteliği'ne işaret eden bir ok ve üst kısımda I Yetkilendirme Filtresi'ne işaret eden bir ok bulunur.
Denetleyici Eylemi İçinde Yetkilendirme
Bazı durumlarda, bir isteğin devam etmesine izin verebilir, ancak davranışı sorumluya göre değiştirebilirsiniz. Örneğin, döndürdüğünüz bilgiler kullanıcının rolüne bağlı olarak değişebilir. Denetleyici yönteminde ApiController.User özelliğinden geçerli sorumluyu alabilirsiniz.
public HttpResponseMessage Get()
{
if (User.IsInRole("Administrators"))
{
// ...
}
}