Asp.Net Web Api ile oluşturulan uygulamalar dış dünyaya tamamen açık olmayacaksa yani bazı kaynaklar sadece kayıtlı kullanıcılara sunulacaksa bu noktada Api güvenliğinin sağlanması gerekmektedir. Api güvenliği temelde, sistem kullanıcıların kim olduğunu ve hangi kaynaklara erişebileceğini belirleyen bir mekanizmanın oluşturulması ile sağlanabilir.
Güvenlik mekanizmalarının oluşturulmasında kullanılan iki temel kavram vardır. Bunlar:
- Kullanıcı Doğrulama (Authentication), bir kullanıcının kim olduğunu belirleme işlemidir.
- Kullanıcı Yetkilendirme (Authorization), belirlenen kullanıcıların hangi kaynaklara erişeceğini belirleme işlemidir.
Kullanıcı Doğrulama (Authentication)
Web Api çatısı, kullanıcı doğrulama işleminin host tarafından gerçekleştiğini varsayar. Örneğin IIS üzerinde host edilmiş bir uygulama, ilgili HTTP modülü tarafından doğrulanır. Kendi yazdığımız bir HTTP modülü üzerinde de doğrulama işlemini gerçekleştirebiliriz. Ancak alternatif olarak doğrulama işlemi Web Api HTTP Message Handler tarafından da gerçekleştirilebilir. Bu yöntemde sorumluluk Web Api message handler tarafına yüklenmiş olur. Bu durum aşağıdaki sebeplerden dolayı geliştiricide bazı çekinceler meydana getirebilir:
- HTTP modülleri, Asp.Net iletim hattı(pipeline) boyunca tüm talepleri kontrol eder, ancak Web Api message handler tipleri sadece Web Api üzerine yönlendirilen talepleri kontrol eder.
- Geliştirici isterse Route mekanizmasına göre doğrulama yapabilir.
- HTTP modülleri IIS için özeldir, message handler tipleri ise Web Api host ortamı için özeldir. Web host veya self host.
- HTTP modülleri IIS logging ve denetim sürecine dahildir.
- HTTP modülleri, iletim akışın başlamadan önce çalışır. Eğer message handler kullanırsanız handler çalışana kadar kimlik bilgileri belirlenmez.
Hangi yöntem kullanılmalı konusunda kısaca şunu söylemek gerekir ki: Eğer web host kullanılacaksa HTTP modül kullanmak iyi bir seçim olacaktır. Ancak self host kullanılacaksa Web Api message handler kullanmak uygun olacaktır.
Eğer kullanıcı doğrulama işlemini kendi özel sınıfınız yardımıyla gerçekleştirdiyseniz iki farklı noktaya kullanıcı bilgilerini kaydetmelisiniz. Bunlar:
- Thread.CurrentPrincipal
- HttpContext.Current.User
private void SetPrincipal(IPrincipal principal) { Thread.CurrentPrincipal = principal; if (HttpContext.Current != null) { HttpContext.Current.User = principal; } }
Self host durumunda Thread.CurrentPrincipal kullanılır, Web host durumunda ise HttpContext.Current.User kullanılır.
Kullanıcı Yetkilendirme (Authorization)
Yetkilendirme işlemi, iletim hattında(pipeline) doğrulama işleminden sonra gelir. Yetkilendirme sırasında önce kullanıcının doğrulanmış olup olmadığı kontrol edilir. Yetkilendirme işlemi Controller veya Action seviyesinde gerçekleştirilebilir. Akışta yetkilendirme filitreleri controller ve action metodlarından önce çalışır.
Web Api uygulamalarında yetkilendirme işlemi filtreler akışa dahil edilir. Varsayılan olarak AuthorizeAttribute filtresi vardır. Filtreler iletim hattında ki akışa 3 şekilde dahil edilebilir.
- Global seviyede
- Controller seviyesinde
- Action metod seviyesinde
Filtre aşağıdaki şekilde global seviyede akışa dahil edilebilir.
public static void Register(HttpConfiguration config) { config.Filters.Add(new AuthorizeAttribute()); }
Eğer filtreler global olarak akışa dahil edilirse tüm talepler doğrulama işlemi için kontrol edilir. Eğer doğrulanmamış ise kullanıcıya Http 401 hata kodu döndürülür.
Controller seviyesinde sınırlandırma yapmak için filtre, attribute olarak kullanılır.
[Authorize] public class ValuesController : ApiController { public HttpResponseMessage Get(int id) { ... } public HttpResponseMessage Post() { ... } }
Action seviyesinde sınırlandırma yapmak için de aynı attribute kullanılır.
public class ValuesController : ApiController { [Authorize] public HttpResponseMessage Get(int id) { ... } }
Bir controller sınıfı Authorize attribute ile işaretlendiğinde içerisindeki tüm action metodları sınırlı erişime dahil olur. Ancak bazı action metodları sınırlamadan çıkarmak için AllowAnonymous attribute kullanılabilir.
[Authorize] public class ValuesController : ApiController { [AllowAnonymous] public HttpResponseMessage Get(int id) { ... } public HttpResponseMessage Post() { ... } }
Authorize attribute kullanırken kullanıcı adı ve rol adı belirlemek de mümkündür. Bu şekilde sadece ilgili rol veya kullanıcıya izim verilmiş olur. Örnek:
[Authorize(Users="Bayram")] public class ValuesController : ApiController{} [Authorize(Roles="Admin")] public class ValuesController : ApiController{}
Özel Yetkilendirme
Kendi özel sınıflarımızla yetkilendirme işlemini gerçekleştirmek istiyorsak oluşturacağımız sınıfı aşağıdaki tiplerden birinden türetmek gerekir.
- AuthorizeAttribute, geçerli kullanıcı ve rolüne göre dayalı doğrulama için kullanılır.
- AuthorizationFilterAttribute, senkron bir yetkilendirme için kullanılır. Geçerli kullanıcı olmasına gerek yoktur.
- IAuthorizationFilter, asenkron bir yetkilendirme için kullanılır. Örneğin dosya sistemi veya network kullanıdığı durumlarda.
Kaynak: http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api
Faydalı bir makale olmuş teşekkürler hocam. Fakat web api için sadece authorize işlemi yeterli oluyor mu? Yani MVC sitesinde olduğu gibi cookie göndererek mi süreç devam ediyor?
Web Api uygulamaları geliştirilirken platform bağımsızlığı hedeflenir. Yani bir oluşturulan Web Api Javasript , Android, IOs gibi uygulamalarda kullanılabilmelidir. Bunu için Cookie gibi teknolojiler yerine günümüzde ağırlıklı olarak Token temelli iletişimler kullanılır. Yanı Api’yi kullanmak için önce kullanıcı adı ve şifre ile veya bir ApiKey ile Token alınır. Sonra alınan Token diğer sorgular için kullanılır. Doğrulama işlemleri token yöntemi dışında Basic, Digest, Kerberos, Public-Key-Certificate gibi yöntemlerle de yapılabilir. Bu arada başka bir konuya da ufaktan girmiş olduk 🙂
Eee hocam yeni konuya girdiğinize göre açıklayıcı bir makalesini de yazarsınız umarım 🙂 Bu konuda Türkçe kaynak sıkıntısı var malum.
@samet hocam hemen boşluğu yakalamış 🙂 Elimden geldiğince yazmaya çalışırım inşallah.
Bütün controller da kullanıcı kontrolü için yalnızca [Authorize] tanımlamak yeterli mi her bir controller için ?
[Authhorize] attribute kullanıcının sisteme giriş yapıp yapmadığını kontrol eder. Bu kontrolü yaparken de aslında HttpContext.Current.User Property kontrol edilir. Dolayısıyla kullanıcıların doğrulanmadan Controller veya Action metodlara ulaşmasını istemiyorsak [Authorize] attribute kullanmalıyız.
Peki,kullanıcıların doğruluğunu nasıl kontrol edebiliriz ve henüz log out olup olmadığını kontrolü için cookie mi kullanmak gerek ?
Teşekkürler
Web Api için kullanıcı doğrulama işlemi BacisAuthentication veya Token yöntemi ile yapılır. Örneğin bir HttpHandler yardımı ile kullanıcı bilgilerini doğrulayayıp HttpContext.Current.User için bir GenericIdentity oluşturabilirsiniz. Cookie mantığı REST servisler için uygun değildir. Normal Web uygulamalarında Cookie bilgileri internet tarayıcı ve Sunucu arasında gezinir. Web api gibi REST servislerinde ise örneğin BasicAuthentication kullanılır ise sunucu ve kullanıcı arasında her defasında kullanıcı adı veya şifresi gezinir.
Güvenlik konusunda neler yapılabilir ,ataklara karşı vs ?