Asp.Net Web Api ile Kullanıcı Doğrulama ve Yetkilendirme

15 Şub

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.

webapi_auth01

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.

webapi_auth02

Kaynak: http://www.asp.net/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api