Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Asp.NET MVC – Web Api Token Authentication

Bir önceki Asp.NET MVC – Web Api Nedir? Nasıl Oluşturulur? başlıklı yazımda Web Apilerin ne olduklarına ve nasıl oluşturulduklarına değinen içeriği kaleme(klavyeye) almıştık. Bu içeriğimizde ise oluşturduğumuz Web Apilerde Token Authentication ile kullanıcı taraflı doğrulama uygulamasını inceliyor olacağız.

Token Authentication Nedir?

“Token” kelimesi Türkçe’de “jeton”, “işaret”, “anahtar” vs. şeklinde karşılığı olan bir kelimedir. Ben burada “jeton” tabirini tercih etmekteyim.

Token Authentication; oluşturduğumuz Web API’yi kullanmak isteyenlere karşı, geliştiriciler tarafından kontrol ve güvenlik mekanizması sağlayan bir doğrulama yöntemidir. API geliştiricisi, token authentication yöntemini kullanarak Apiyi kullanmak isteyen clientlara denetleme sağlamakta ve bu şekilde kontrollü bir açılım uygulamaktadır. Denetlemede doğru kullanıcı adı ve şifreyi giren kullanıcıya server tarafında belirli bir süreliğine bir adet token oluşturulur. Kullanıcı bu tokenı kullanarak Web API’nin nimetlerinden faydalanabilmektedir.

Token Authentication İçin Hangi Kütüphanelerin Projeye Entegrasyonu Gereklidir?

Token Authentication’ı sağlayabilmek için aşağıdaki kütüphanelerin projeye entegre edilmesi gerekmektedir;

  • Microsoft.AspNet.WebApi.Owin
  • Microsoft.Owin.Security.OAuth
  • Microsoft.Owin.Cors
  • Microsoft.Owin.Host.SystemWeb

İlgili kütüphanelerin entegrasyonunu “NuGet Package Manager” penceresinden sağlayabilirsiniz.

Token Authentication’ın Uygulanması

Şimdi varsayalım ki elimizde aşağıdaki Web API Controller bulunsun.

    public class PersonelController : ApiController
    {
        NorthwindEntities db = new NorthwindEntities();
        public IEnumerable<Personel> GetAllPersonel() => db.Personeller.Select(p => new Personel
        {
            Adi = p.Adi,
            Soyadi = p.SoyAdi,
            Unvan = p.Unvan
        });
        public Personel GetPersonel(int id) => db.Personeller.FirstOrDefault(p => p.PersonelID == id);
        public IHttpActionResult PostPersonel(Personel personel)
        {
            db.Personeller.Add(personel);
            db.SaveChanges();
            return Ok(personel);
        }
    }

Bu apiye özel bir Token Authentication oluşturalım.

İlk olarak projeye “Startup.cs” dosyası ekleyelim.

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration httpConfiguration = new HttpConfiguration();
            ConfigureOAuth(app);
            WebApiConfig.Register(httpConfiguration);
            app.UseWebApi(httpConfiguration);
        }

        void ConfigureOAuth(IAppBuilder app)
        {
            //Token üretimi için authorization ayarlarını belirliyoruz.
            OAuthAuthorizationServerOptions oAuthAuthorizationServerOptions = new OAuthAuthorizationServerOptions()
            {
                TokenEndpointPath = new PathString("/token"), //Token talebini yapacağımız dizin
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), //Oluşturulacak tokenı bir gün geçerli olacak şekilde ayarlıyoruz.
                AllowInsecureHttp = true, //Güvensiz http portuna izin veriyoruz.
                Provider = new ProviderAuthorization() //Sağlayıcı sınıfını belirtiyoruz. Birazdan bu sınıfı oluşturacağız.
            };

            //Yukarıda belirlemiş olduğumuz authorization ayarlarında çalışması için server'a ilgili OAuthAuthorizationServerOptions tipindeki nesneyi gönderiyoruz.
            app.UseOAuthAuthorizationServer(oAuthAuthorizationServerOptions);

            //Authentication Type olarak Bearer Authentication'ı kullanacağımızı belirtiyoruz.
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

            //Bearer Token, OAuth 2.0 ile gelen standartlaşmış bir token türüdür.
            //Herhangi bir kriptolu veriye ihtiyaç duyulmaksızın client tarafından token isteğinde bulunulur ve server belirli bir zamana sahip access_token üretir.
            //Bearer Token SSL güvenliğine dayanır.
        }
    }

Yukarıdaki “Startup.cs” sınıfını incelerseniz eğer “Configuration” metodunda gerekli http konfigürasyonları sağlanmaktadır. “ConfigureOAuth” isimli metotta ise token üretimi için gerekli authorization oluşturulmakta ve gerekli provider sınıfı tanımlanmaktadır.

Tanımladığımız “ProviderAuthorization” isimli provider sınıfımızıda incelersek eğer;

    public class ProviderAuthorization : OAuthAuthorizationServerProvider
    {
        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            context.Validated();
        }
        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            //Domainler arası etkileşim ve kaynak paylaşımını sağlayan ve bir domainin bir başka domainin kaynağını kullanmasını sağlayan CORS ayarlarını set ediyoruz.
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

            //Kullanıcının access_token alabilmesi için gerekli validation işlemlerini yapıyoruz.
            if (context.UserName == "Gençay" && context.Password == "SebepsizBoşYereAyrılacaksan")
            {
                ClaimsIdentity identity = new ClaimsIdentity(context.Options.AuthenticationType);
                identity.AddClaim(new Claim("sub", context.UserName));
                identity.AddClaim(new Claim("role", "user"));

                context.Validated(identity);
            }
            else
            {
                context.SetError("hata", "Kullanıcı adı veya şifre hatalı.");
            }
        }
    }

Yukarıdaki kod bloğunu incelerseniz eğer, oluşturmuş olduğumuz ProviderAuthorization sınıfının client erişimine izin verebilmek için ValidateClientAuthentication metodunu OAuthAuthorizationServerProvider sınıfından override ettik. Benzer şekilde ProviderAuthorization sınıfının kaynak erişimine izin verebilmek için de GrantResourceOwnerCredentials metodunu override etmiş bulunmaktayız.

Artık Token Authentication için gerekli tüm çalışmaları gerçekleştirmiş bulunmaktayız. Dolayısıyla ilgili Web Apimizde doğrulama güvenliği uygulamak istediğimiz metotları “Authorize” attribute’u ile işaretlememiz yeterlidir. Tabi ben tüm metotlarımda bu doğrulamayı istediğim için komple web api sınıfını ilgili attribute ile işaretlemekteyim.

    [Authorize]
    public class PersonelController : ApiController
    {
        NorthwindEntities db = new NorthwindEntities();
        public IEnumerable<Personel> GetAllPersonel() => db.Personeller.Select(p => new Personel
        {
            Adi = p.Adi,
            Soyadi = p.SoyAdi,
            Unvan = p.Unvan
        });
        public Personel GetPersonel(int id) => db.Personeller.FirstOrDefault(p => p.PersonelID == id);
        public IHttpActionResult PostPersonel(Personel personel)
        {
            db.Personeller.Add(personel);
            db.SaveChanges();
            return Ok(personel);
        }
    }

Evet… Şu noktadan itibaren Postman uygulaması üzerinden herhangi bir GET ya da POST metoduna requestte bulunduğumuzda aşağıdaki hatayla karşılaşacağız.

{
“Message”: “Authorization has been denied for this request.”
}

Gördüğünüz üzere web apimiz token üretmeyen kullanıcılara nimetlerini sunmamaktadır.

Öncelikle token üretmemiz gerekecektir. Haliyle ilk olarak aşağıdaki linki belirtilen headers ve body özellikleriyle tetikleyerek gerekli kullanıcı adı ve şifre ile tokenımızı elde edelim.

http://localhost:*****/token

Headers’a eklenecek parametreler;

Header Value
Accept application/json
Content-Type application/x-www-form-urlencoded

Body’e eklenecek parametreler;

Key Value
grant_type password
username Gençay
password SebepsizBoşYereAyrılacaksan

Asp.NET MVC - Web Api Token Authentication
Görüldüğü üzere tokenımızı elde etmiş olduk. Artık bu tokenı kullanarak Web Api’de istediğimiz herhangi bir metoda erişebiliriz.

GET ya da POST metotlarına erişmeye çalışırken her ikisinde de ortak olan headers özelliklerini aşağıdaki gibi vermemiz yeterli olacaktır.

Header Value
Content-Type application/json
Authorization Bearer (….D4buSqsfoyuXEdvWpvpBGbHBTP9FAY…)

Burada dikkat etmeniz gereken nokta, Authorization’a token değerini yazarken başına “Bearer” değerini yazmayı unutmayınız.

Asp.NET MVC - Web Api Token Authentication
Asp.NET MVC - Web Api Token Authentication
Asp.NET MVC - Web Api Token Authentication
Görüldüğü üzere web api’de ki her bir metot için elde ettiğimiz token ile başarılı requestlerimizi gerçekleştirmiş bulunmaktayız.

Bu satırlardan itibaren Asp.NET MVC – Web Api uygulamalarında Token Authentication’ın nasıl sağlandığını yeterince incelemiş bulunuyoruz. Umarım faydalı bir içerik olmuştur.

Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar dilerim…

Bunlar da hoşunuza gidebilir...

15 Cevaplar

  1. Semih Şenocak dedi ki:

    Emeğinize sağlık..
    İşlemleri Wep Api projeme uygulayıp çalıştırıdığımda aşağıdaki hatayı almaktayım. Bu konu ile ilgili yardımcı olabilir misiniz?
    The following errors occurred while attempting to load the app.
    – No assembly found containing an OwinStartupAttribute.
    – No assembly found containing a Startup or [AssemblyName].Startup class.
    To disable OWIN startup discovery, add the appSetting owin:AutomaticAppStartup with a value of “false” in your web.config.
    To specify the OWIN startup Assembly, Class, or Method, add the appSetting owin:AppStartup with the fully qualified startup class or configuration method name in your web.config.

  2. mehmet kamacı dedi ki:

    merhabalar,
    mvc projemin view bölümüne taşımak isterim yani postman olmadan kullanıcı bilgileri girebileceği bir login page ile nasıl entegre edebilirim.

    teşekkürler.

  3. Savas dedi ki:

    Tesekkurler

  4. Furkan dedi ki:

    Şifreyi SebepsizBoşYereAyrılacaksan olarak gördüm sadece ölüler görür… bir sigara yaktım

  5. Bedirhan dedi ki:

    Merhaba,
    Uzun süredir owin kütüphanesini kullanarak TOKEN işlemlerini yapıyorum. Oluşan TOKEN’lara nasıl erişebiliriz? Senaryo: Admin aktif kullanıcı listesine giriş yapar ve karşısına aktif kullanıcı listesi gelir, kullanıcı listesinde seçili kullanıcıyı sistemden atabilir. Bu senaryoyu yapabilmem için bana 2 ayrı metot lazım;1. metot aktif token listesini verebilecek, 2. metot token id si verilecek veya başka bir değer alıp signout yaptırması gerek. Bazı kaynaklara baktım çözüm bulamadım, siz sürekli projeler geliştirdiğinizden illa ki bu senrayoya benzer iş yapmışsınızdır diye sormak istedim. Yardımcı olursanız çok sevinirim.

  6. Burak dedi ki:
    WebApiConfig.Register(httpConfiguration);
    

    kısmını yazdığımda derleme hatası alıyorum. .net 7.0 ile çalışıyorum. yardımcı olabilir misiniz ?

  7. serdar dedi ki:

    merhaba yanlışım varsa düzeltin heryerde server side tarafında login bilgilerileri şifreleyip db ye yazmayı göstermişler.Oysaki site https değilse browser üzerindeki header da giriş bilgileri elde ediliyor bunun için aynı wifi ağındaki browser ların header larını fiddler tarzı bir programla ele geçirebilinir.Bu yüzden bana göre client side tarafında bunların şifrelenmesi ve server bu şekilde gönderilmesi.Yazınız güzel olmuş

  1. 12 Şubat 2019

    […] yazılarımdan olan Asp.NET MVC – Web Api Token Authentication başlıklı içeriğimde standart Asp.NET MVC’de Web API kullanırken nasıl Token […]

  2. 13 Şubat 2020

    […] Asp.NET MVC – Web Api Token Authentication […]

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir