İçeriğe geç →

Asp.Net Web API – Token Based Authentication

Merhaba arkadaşlar, bu makalemde Asp.Net Web API ile RESTful servis geliştirirken Token Based bir Authentication işlemi nasıl yapıldığına dair örnek bir proje yapacağız.

RESTful’ün önemini kısaca hatırlamak gerekirse:

  • Fazlasıyla basit ve esneklik sağlamaktadır.
  • REST’in HTTP protokolü üzerine kurulmuş olmasıyla beraber günümüz modern web dünyasındaki bir çok uygulamalar kendini browser tabanlı uygulamalara bırakıyor ve artık bir çok işlem client-side tabanlı yapıldığı için REST servisleri bize bir artı daha sağlıyor bu anlamda.

Özünde RESTful servisleri bize client-server arasındaki yapacak olduğumuz veri transferini SOAP veya RPC gibi kompleks mimariler yerine daha hafif ve esnek bir şekilde yapabilme olanağı sağlıyor.

REST mimarisini hatırladığımıza göre, gelelim şimdi nedir bu Token Based Authentication?

Günümüz çağında geliştirilen neredeyse tüm uygulamaların bir mobil bacağı bulunmaktadır veya mobil tarafına da destek verebilecek şekilde servis mimarileri geliştirilmektedir. REST mimarisi üzerine kurulan bir serviste ise güvenlik işlemlerini ele alabilmek, client’ı yetkilendirebilmek için Token (Jeton) bazlı bir yetkilendirme işlemi yapılmaktadır.

Token Based Authentication işleminin yaşam döngüsüne bakmak istediğimizde ise:securitypattern

  • Client kendi güvenlik bilgilerini girer ve bu bilgiler Authorization Server‘a gönderilir
  • Authorization Server bu bilgileri doğrulursa, client’a bir Access Token Http Response’u döner.
  • Client artık erişmek istediği servislere, elde etmiş olduğu Access Token’ı  Http Request’in Authorization Header‘ına ekleyerek erişim sağlar.

Bu ön bilgilerden sonra hemen örneğimize geçelim. Öncelikle örneğimizde Authentication işlemleri için OAuth 2.0 protokolü ile sağlayacağız ve bunun için Microsoft’un Owin kütüphanesinden yararlanacağız.

Owin temelinde IIS ile Application arasında kendi pipeline’ını kuruyor ve işlemleri burada handle ediyor. Lightweight bir pipeline’a sahiptir.

OWIN__2

AspNetWebAPIOAuth isminde bir Asp.Net Web Application oluşturuyorum. Oluştururken Template kısmından Empty seçip Core Referansını ise Web API seçerek tamamlıyorum.

Projemizi oluşturduğumuza göre hemen projemiz üzerine sağ tıklayarak NuGet Package Manager’ı açıp Search kısmından OAuth yazarak çıkacak olan sonuçlar içinden Microsoft.AspNet.WebApi.Owin, Microsoft.Owin.Host.SystemWeb ve Microsoft.Owin.Security.OAuth‘u seçerek projemize kuruyoruz.

Proje içerisine OAuth isimli bir klasör ekleyerek servis çalışmaya başlarken Owin pipeline’ını ayağa kaldırabilmek için Startup sınıfını hazırlamaya başlıyoruz ve içerisinde gerekli konfigürasyon ayarlarını WebApiConfig‘e register edip, Owin Server üzerinde uygulama oluşurken kullanacağı konfigürasyon ayarınıda belirtiyoruz.

Startup.cs:

Owin ayarlarını başlangıçta içeren sınıfımızı oluşturduk. Sınıf satırlarındaki yorumlarda da belirttiğimiz üzere, Authentication type olarak Bearer Authentication kullanacağız. Sebebi ise daha fazla lightweight olup OAuth 2.0 ile standart bir hale gelmesi ve hem client hemde server side için authentication işlemlerini daha fazla kolaylaştırmasıdır. Ayrıca tüm işlemler her ne kadar bir access token üzerinden yürüyecek olsada, SSL ile client ile server arasındaki veri güvenliği sağlanmalıdır.

OAuthAuthorizationServerOptions ayarlarını tanımlarken Provider olarak OAuthAuthorizationServerProvider sınıfından miras alarak türeteceğimiz SimpleAuthorizationServerProvider ‘ı seçtik. Şimdi gelelim bu provider’ın kodlarını incelemeye. Öncesinde daha önce açtığımız OAuth klasörünün içine hemen bir Providers isminde klasör daha açarak içerisinde ilgili sınıfımızı oluşturuyoruz.

SimpleAuthorizationServerProvider.cs:

OAuthAuthorizationServerProvider sınıfının iki metodunu ezdiğimizi görüyoruz. Bunlardan birincisi, Client’ı doğrulamak için ki direkt olarak doğruladık biz. İkincisi ise asıl kaynak erişimine verilecek yetkilerin ayarlandığı ana kısım. Öncelikle burada CORS ayarlarını gerçekeleştirdik. Hemen CORS nedir hatırlatması yapmak gerekirse:

CORS domain’ler arası kaynak paylaşımını sağlamaya yarayan bir mekanizmadır. Bir domain’in bir başka domain’in kaynağını kullanabilmesini sağlar.

Hızlıca CORS’u da tekrardan hatırladığımız üzere devamında koda baktığımızda da net bir şekilde görüldüğü gibi validation işlemlerini gerçekleştiriyoruz. Eğer kullanıcı geçerli bir kullanıcı ise bir kimlik yaratıp, context üzerinde doğruluyor.

Evet şuan Owin için OAuth 2.0 implementasyonunu gerçekleştirmiş bulunuyoruz. Şimdi gelelim Controller üzerinde ki kullanımına. Hemen Controllers kısmına OrdersController ekliyorum ve içine List isminde bir metot tanımlıyorum. Form Authentication’dan da hatırlayabileceğiniz üzere metotların üstüne attirbute olarak [Authorize] attributunu ekliyorduk, Owin içinde aynı attribut’u kullanıyoruz.

OrdersController.cs:

Api tarafında herşey hazır olduğuna göre projemizi test edebiliriz. Ben tool olarak Postman’ı tercih ediyorum siz isterseniz Fiddler Composer’da kullanabilirsiniz. Postman data gönderirken bana daha fazla esneklik sağlıyor açıkcası. 🙂

Öncelikle direkt olarak ilgili api metodumuza erişmeye çalıştığımızda alacağımız sonuca bir bakalım:

oauth_hata

 

api/Orders/List url’i ile GET isteği attığımızda Authorization hatası aldığımızı görüyoruz. Öncelikle /token path’i ile belirttiğimiz adrese gidip geçerli bir access_token almalıyız.

Bunun için POST tipinde /token url’ine Headers’a ve Body’e bir kaç parametre set ederek gitmemiz gerekmektedir.

Headers’e eklenecek parametreler:

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

Body’e eklenecek parametreler:

data tipi x-www-form-urlencoded olarak seçilip,

Key: grant_type                 Value: password
Key: username                  Value: Gokhan (Kullanıcı adınız)
Key: password                   Value: 123456 (Şifreniz)

İlgili bilgileri girdikten sonra POST işlemini gerçekleştirelim ve gelen sonuca bakalım:

oauth_token

 

Geriye dönen JSON sorgusunda access_token oluşmuş ve expires_in süresi ile geldiğini görüyoruz. Bu süreyi hatırlarsak Startup kısmında konfigürasyon bölümünde AccessTokenExpireTimeSpan propertysi ile vermiştik.

Artık bu token’ı kullanarak tekrardan api/Orders/List url’ine tekrardan bir GET sorgusunda bulunalım. Fakat bu sefer ilgili token’ı Header’a ekleyerek gönderiyoruz.

Headers’e eklenecek parametreler:

Header: Content-Type      Value: application/json
Header: Authorization       Value: Bearer jyMJNFpYdBOZxoUZsutu7vNe4JY–kdvdjTylrJi_rZPC5VUOFSTvej-Sq0jvCj1gYbg0HHAk6ILoj0U7G3zCYcl1lK9tA6YwMGODccsorhjwDTzuuGprU00f5j4Ly1DUhS54TejbrZtn1RMegSCXFfixjkYkeXeVd6eP0eGGrAr6f3ICVGz7KASR28soQEh_4sXpOZLmDpDJFKKAEoI_q0h9_7qvfIIjm8t0lDcCp4

Token tipimiz Bearer olduğu için headerda Authorization kısmının değerine access_token’ı girmeden önce Bearer tag’ini ekleyip daha sonrasında access_token’ı ekliyoruz.

oauth_access

 

Servisten başarıyla bilgileri çektiğimizi görüyoruz. Bir sonraki Web API konumda ise Custom Token Based Authentication işlemi nasıl gerçekleştirilebilir hakkında bir şeyler yazmayı planlıyorum. Şimdilik sağlıcakla kalın.

AspNetWebAPIOAuth

Bu makale toplam (38417) kez okunmuştur.

115
3



Kategori: Asp.Net Web API

160 Yorum

  1. necati necati

    Makale çok güzel, ellerinize sağlık. Benim bir sorum olacak, postman’la değil de js ile bu işlemleri yapmak istediğimde;
    OPTIONS http://localhost:49516/Api/Students 405 (Method Not Allowed)jQuery.ajaxTransport.options.send @ jquery.js:9664jQuery.extend.ajax @ jquery.js:9215(anonymous function) @ app.js:32
    index.html:1 XMLHttpRequest cannot load http://localhost:49516/Api/Students. Response for preflight has invalid HTTP status code 405

    hatası alıyorum. Token alıp headers kısmından yolluyorum.

  2. Eren Eren

    Yazı için teşekkürler. Postman kullanmadan nasıl ajax isteği gönderebileceğimizi anlatabilir misiniz?

    • Merhaba, kusura bakmayın geç yanıt için yoğunluktan bakamıyorum bu aralar.

      Aşağıdaki gibi bir ajax isteği ile access token’ı alabilirsiniz.

      < script type="text/javascript">
      function GetToken() {
      $.ajax({
      type: ‘POST’,
      url: ‘/Token’,
      dataType: ‘json’,
      data: { “grant_type”: “password”, “username”: “Gokhan”, “password”: “123456” },
      success: function (response) {
      // Access token’ı bu şekilde alabilirsiniz.
      alert(response.access_token)
      }
      });
      }
      < /script>

  3. Melih Melih

    Merhabalar,

    Öncelikle paylaşımınız için teşekkürler.

    grant_type alanını authorization_code olarak geçtiğimde invalid_grant hatası alıyorum. Bu hatayı düzeltmek için neler yapabilirim?

  4. murat_k murat_k

    Merhaba hocam, token request ile dönen JSON nesnesi (access_token, token_type, expires_in) parametrelerini döndürmektedir. Eğer kullanıcı adı ve rollerini de (access_token, token_type, expires_in, username) almak istiyorsak ne yapmalıyız. token bilgisinin yanında username gelsin istiyorsak bunu kodda nereye eklemeliyiz?

    • Merhaba
      client o token bilgileri ile server’a bir request isteği bulunduğunda, eğer token bilgisi geçerli bir token ise SimpleAuthorizationServerProvider class’ının içerisinde kullanıcı bazlı identity oluşturarak “identity.AddClaim(new Claim(“sub”, context.UserName));” satırı ile istediğimiz property’lerini doldurmuştuk. Bu bilgilere server tarafında kullanıcı authentication işleminden geçirildikten sonra ulaşabilirsin. Bu bilgilere ulaşabilmek için ise, System.Web.Http namespace’i altında bulunan User context’i üzerinden ulaşabilirsin. Saygılar.

  5. AbbA AbbA

    Merhabalar,
    Oldukça temiz bir iş, ellerinize sağlık. Custom Token Auth dan önce Refresh token konusuna da basit bir örnekle değinirseniz çok daha faydalı olacağı konusundayım. Lakin neden ihtiyaç duyulduğu konusunda bazı durumlarda ikilemde kalıyorum.

    • AbbA AbbA

      Replace(parent.comment,”olacağı konusundayım.”,”olacağı kanısındayım.”);

    • Merhaba, teşekkür ederim öncelikle. Dürüst olmak gerekirse bu konulara daha derinlemesine Şubat ayı gibi çıkacak olan Asp.NET Web API kitabımda değiniyorum. O yüzden şimdilik daha fazla makale ekleyemiyorum bu konuda. Kısaca ihtiyaç duyulma sebebine değinecek olursak: Eğer belirli bir expire süresine sahipse token fakat API’ı consume eden client hala session’a ihtiyacı varsa, tekrardan login olma ihtiyacı yerine refresh token ile yeni bir authorization token isteğinde bulunarak gerçekleştirebilir. Bu sayede client username ve password gibi bilgileri token lifecycle’ı boyunca tekrardan taşımasına ve validation yapmasına gerek yoktur.

      Saygılarımla.

      • AbbA AbbA

        Merhabalar;
        Piyasaya çıkacak olan kitabınız için şimdiden başarılar diliyorum.Cevabınız için de çok teşekkürler, çok fazla olmuyorsam tam da takıldığım kısım işte burası; Sizin örneğinizde; Bir kullanıcı için, giriş yaptığı sayı kadar (teoride sonsuz) 24 saat geçerli tokenlar üretiyor;

        1) Bu bir güvenlik sıkıntısı doğurmaz mı?
        – Sonuçta servise erişmek için, bir kullanıcının birden fazla token ı olabiliyor. Geçmişe dönük oluşturulmuş tüm tokenları geçersiz kılacak bir yöntem daha mantıklı değil mi? Mesela kullanıcı yeni bir validasyon yaptığında. Ayrıca en önemli problem; Kullanıcı giriş yaptı, 24 saatlik token üretildi, sonra kullanıcı şifresini değişti, ancak üretilen tokenı kullanan ile diğer uygulamalar hala daha kaynaklara erişebilir durumda çünkü token 24 saat geçerli.(içerde her authorize durumunda fazladan bir kontrol yapmıyorsan)

        2) Refresh token ile sürekli kullanıcıdan giriş yapmasını önleyerek kullanıcı bilgilerini güvene alabiliyoruz.
        – Çok iyi de, ben servis sunucusu olarak piyasaya geçerli bir token sunduğumda, uygulama o token ı sürekli refresh ile uzatıp, süresiz olarak kullanıcı kaynaklarına erişim sağlayabilir. Kullanıcı istediği kadar şifresini değiştirsin. (içerde her authorize durumunda fazladan bir kontrol yapmıyorsan)

        Yada ben bu TOKEN olayını yanlış mı anlıyorum.

        • Merhaba tekrardan, İlk olarak 24 saat olayını olması gereken expire süresi olacak şekilde algılamayın. Bu sadece bir örnek olduğu için o şekilde verdim. 🙂 Sonuçta bu PoC (proof-of-concept)’deki amacım; custom olarak bir token provider nasıl oluşturulur idi. Dediğiniz gibi güvenlik bacağı ise ayrı bir kısımdır. Gerek login aşamasında gerekse de access_token’ın lifecycle’ı boyunca sağlanacak olan. Öte yandan refresh_token’da bir expire süresine sahiptir. Expire süresi boyunca belirlenen expire dahilinde yeni bir access_token alabilir client. Amaçta budur zaten. Refresh_token expire olduğunda ise tekrardan login olup yeni bir access_token alması gerekmektedir.

          İyi günler dilerim.

  6. Ümit Ümit

    Merhaba,
    Öncelikle anlatımınız için teşekkürler.
    Sormak istediğim şu; OAuth ile HttpPost attribute’una sahip metodları Authorize edebiliyor muyuz? Bununla ilgili açıklayıcı bir kaynak bulamadım. Cevaplarsanız memnun olurum.

    • Merhaba, POST veya GET farketmez, Authorize işlemlerini gerçekleştirebilirsiniz.

      • Ümit Ümit

        Denemelerimde Authrorize ve HttpPost’u birlikte kullandığımda action’a ulaşamıyorum. Bununla ilgili küçük bir örnek paylaşabilir misiniz?

  7. Rıdvan Rıdvan

    Merhaba token uygulamasını birden fazla sunucuda çalıştırdığım taktirde. A sunucusunda aldığı tokenı B sunucusunda nasıl doğrulatabilirim.

    • Merhaba. Bu işlem gerçekleştirebilmek için config’ler içerisine machine key’lerin aynı olarak belirlenmesi gerekmektedir. Yani hem token api üzerinde hemde api’ı kullanacak olan uygulama üzerindeki config’ler, aynı machine keylere sahip olmalıdır. Decription işlemleri için machine key içerisinde bulunan “validationKey” ve “decryptionKey” node’ları kullanılmaktadır. Saygılarımla.

      • Rıdvan Rıdvan

        Peki ben token sahibinin bilgilerine api tarafında nasıl ulaşabilirim.
        Yalnızca token geldi ve method çalıştırmam isteniyor bunu kimin yaptığını loglamak istiyorum.

        • Tanımlamış olduğun identity’lere api tarafına ilgili token’la gelip valide olduğu zaman, System.Web.Http namespace’i altında bulunan User context’i üzerinden ulaşabilirsin.

  8. fatih fatih

    Makaleniz çok yararlı, bunun için teşekkürler. Benim sorum şu: controller veya action bazında grant işlemini nasıl gerçekleştirebiliriz? Mesela haberleri listeleme metodunu kullanabilsin ama haber ekle metodunu kullanamasın. Kullanıcı grubu bazında bu durumu nasıl gerçekleştirebilirim?

    • Merhaba, bu işlemi yapabilmek için client’ı authorize ettikten sonra yeni bir claim eklerken ‘identity.AddClaim(new Claim(“role”, “user”));’ burada istediğiniz custom “role” leri ekleyerek bu “role” değerlerine göre action bazında işlem yapılabilip, yapılamayacağını sınırlayabilirsiniz. [Authorize(Roles = “user”)] gibi. İyi günler dilerim.

  9. Mustafa Mustafa

    Çok güzel bir makale teşekkürler. Veri alışverişinde Bearer kullanıp encrypt yapabilir miyiz? Yaparsak doğru bir yöntem sayılır mı? Amacım verilerin gizliliği.

    • Merhaba teşekkürler. Evet yapabilirsiniz zaten OAuth 2.0 Authorization Framework’ü ile beraberinde gelen Bearer token bir standardizasyon haline gelmiştir. Makale içeriğimiz de buna dayanmaktadır. HTTP protokolü söz konusu olduğu için verilerin gizliliği ne kadar sağlanılabilir bu tartışılır ve sizin architectural tasarımınızada bağlı bir etmen bu. Buna ek olarak da SSL kullanımını önerebilirim.

  10. Tuba Tuba

    Merhaba,
    Gayet anlaşılır ve faydalı bir paylaşım olmuş, teşekkürler. Bir sorum olacak; Owin de token tam olarak nasıl bir yapıda tutuluyor?

    • Store yapısı tamamen size kalmış. Token’lar machine key’lere göre serialize ve deserialize ediliyor. Oluşan token’ı siz store etmelisiniz.

      • Tuba Tuba

        Teşekkür ederim, peki web api dokümantasyonu için ne tavsiye edersiniz? Swagger denedim fakat swagger’da token based authentication’ı ekleyemedim.

          • Murat Murat

            Merhabalar,

            Swagger’ı Windows Service üzerinde self-host koşturduğum web-api ile kullanabiliyormuyuz. Swashbuckle.Core üzerinden yapılıyor görünüyor ama standart win service app yada console app üzerinde yapan birilerini bulamadım

          • Murat Murat

            Tekrar merhabalar,
            Swagger’ı Swashbuckle.Core ile win service üzerinde çalıştırdım. Şimdi biraz custom rooter üzerinde çalışmam gerekiyor.

            Teşekkürler.

          • Merhaba, çalıştırabilmenize sevindim.

  11. Mehmet Mehmet

    Merhaba,

    Bu tür Authentication ile ilgili anlamadığım konu, kullanıcı adı ve şifrenin client tarafında oluyor olmasının güvenlik riski oluşturup oluşturmadığıdır. Yani Web uygulamasında AJAX ile Web Api’ye sorgu gönderirken kullanıcı adı ve şifreyi yazıyoruz.

    url: ‘/Token’,
    dataType: ‘json’,
    data: { “grant_type”: “password”, “username”: “Gokhan”, “password”: “123456” },

    Bu güvenlik bilgilerin bilen biri postman, fiddler gibi bir tool ile çok rahat POST veya GET yapabilecek. Benim derdim Web API’min sadece benim sitemden çağrılıyor olmasıdır. Bunu nasıl yapabilirim. Yani http://www.deneme.com/GetUrun/Kategori/7 şeklindeki bir sorgunun sadece deneme.com çatısı altında yapılmasıdır. Başka bir siteden veya tool aracılığıyla kesinlikle çağrılamamasıdır. Çünkü buradaki “7” değerine rastgele değer gönderilerek sunucudaki tüm data çekilebilir.

    Örneğin bir EXE yazarak aşağıdaki URI’daki adana ifadesi yerine kelimeler yazarak birçok kez call edebiliyorum. Bunu engellemek mümkün mü. HTTP üzerinde özel header mi yazmak gerekiyor Veya Session nesnesi falan mı kullanmak gerekiyor. Server tarafında aynı süre içerisinde çok sayıda post gelirse engelleme yapabilirim belki.
    https://www.sahibinden.com/ajax/search/phrase?q=adana&categoryId=0&_=461305609903

    • Merhaba, ilk olarak kullanıcı adı ve şifre yolluyoruz kısmındaki düşüncenize gelecek olursak; kişi access token alabilmek için ilk adımda bu authentication api’a bu sorguyu göndermek zorunda ve genelde bu api SSL ile korunmaktadır ve SSL ile korunmasıda önerilmektedir. İkinci olarak da AJAX ile göndermek zorunda da değilsiniz, backend de yapabilirsiniz bu işlemi. Asıl sorunuza gelecek olursak da, aynı domain çatısı altında sorgularınızın sadece çağrılmasını istiyorsanız buda CORS (Cross-Origin) olarak adlandırılıyor ve sadece aynı sizin belirlediğiniz URI çatısında istekler cevaplanabiliyor. Burayı inceleyebilirsiniz.

  12. Mehmet Mehmet

    SSL ile korunması dış uygulamaların bunu okumasını, HTTP paketlerinin okunmasını engelleyecek ama AJAX içerisinde bana bir fayda sağlayacak mı. Yani kullanıcı adı ve şifreyi POSTMAN’a yazdığım zaman yine çalışacak.

    İkinci konu AJAX ile göndermek zorunda değilsiniz kısmını biraz daha açabilir miyiz. Bunu nasıl engelleyebiliriz. Mobil uygulama tarafında değil de Web uygulaması tarafında örneğin bir buttona tıklandığı zaman AJAX ile Web API çağırdığımızı düşünelim bu durumda backend’e authentication işlemi nasıl olacak.

    CORS olayı için teşekkür ederim, benim için yönlendirici oldu.

    • Önemli olan zaten dış uygulamaların bunu sniffleyememesi. CORS’u yaparsanız zaten Postman veya Fiddler ile bir istekde bulunamayacaksınız. İkinci olarak da REST API entegrasyonunu bu kadar simple düşünmeyin. Herşeyiniz fontend üzerinden AJAX request’leri ile gelsin, gitsin olamaz ki bu kadar güvenliğe takmış ve önem vermiş durumdaysanız. UI tarafındaki Controller’ınızı bir Gateway olarak düşünün. Artık oradaki business’ınız her neyse, asıl REST API’ınızı consume edecek olan request’ler controller tarafında oluşturabilirsiniz. Bu kısımlar artık sizin yoğurt yiyişiniz ve projenizin mimarı dizaynları ile alakalı bir durum.

  13. ilhan ilhan

    Kitabınız çıktı mı acaba

  14. İLHAN İLHAN

    ASP.NET WEB APİ KİTABINIZ NE ZAMAN ÇIKIYOR

    • Merhaba bazı problemlerden dolayı biraz geçikti bu yaza çıkartma planımız. Proje video’su çekme aşamasındayız. Saygılar.

  15. fatih fatih

    Kardeşim eline sağlik cok guzel bir makele olmus.web api ile calismaya basladigimdan beri nasil güvenlik önlemi alacagimi düşünüyordum.kendi sistemime uyguladim sorunsuz bir sekilde calisiyor tsk ederim.küçük bir sorum olacak facebok twitter foursquere gibi sitelerin apileride ayni mantiktami calismaktadir yanitlarsan sevinirim kolay gelsin.

    • Tam olarak arka plandaki logic’lerini bilemem fakat evet, OAuth 2.0 ile çalışmaktadır.

  16. Kemal Kemal

    Merhaba Gökhan Bey,

    Sorum direk yazı içeriğiyle ilgili değil ama , günümüzde asp.net mvc kullanılan ticari girişimlerde asp.net mvc’nin hazır sunduğu authentication mekanizması mı kullanılıyor?

    • Merhaba, bu çok genel bir soru olmuş. 🙂 Ooradaki developer’in ekmek yiyişi ile alakalı bir durumdur diyeyim. İster .Net içerisinde gelen authentication mekanizmalarını kullanır, ister kendisi custom authentication yapısını geliştirir. Bunu bilemem. 🙂

  17. mehmet mehmet

    merhaba anlatımınız için teşekkür ederim ben servislerimi android client tarafında kullanıyorum bu şekilde nasıl güvenli hale getirebilirim android tarafınndan yani java tarafundanmı sabit kullanıcı adı şifre verip tokeni alıp sunucuya tekrar gönderecegim

    • Merhaba, evet app’inizin ilk login ekranında mecburen authentication sunucunuza token key alabilmek için kullanıcı adı ve şifreyi göndermeniz gerekmektedir. Onun dışındaki işlemlerde elde etmiş olduğunuz token ile ilerleyebilirsiniz.

  18. Oğuz Oğuz

    Merhaba Gökhan bey. Ufak bir sorum olacak.

    1. Büyük çaplı bir Web Projesinde Token güvenliğe ihtiyaç olur mu? Bu güvenlik seviyesi sizce hangi aşamadan sonra gerekli olacaktır? İleride bu projeyi kısmi yada tamamını mobile taşımak gerekirse diye soruyorum…

    2. Tokenları api tarafında nasıl tutmak gerekir sizce? Sonuçta bir ikili yapımız var. Token alan kişi ve Token Key. Bunu Sesion da tutabiliriz yada db ye yazabiliriz.. Sizce hangisi?

    3. Böyle bir Token sistemi ne kadar yorar sistemi? Sürekli her servis çağırımında gidip gidip bakmak gerek kullanıcının Tokenı varmı yok mu? diye..

    • Merhabalar, 1. sorunuz için eğer api based bir sistemle çalışıyorsanız ve internal olan resource’larınızı daha sonra dışarıya extend edecekseniz eğer token based bir güvenliğe ihtiyaç duyabilirsiniz. 2. sorunuz için token’ları api tarafında tutmayacaksınız, token yapisi sizin göndermiş olduğunuz kullanıcı adı ve şifreye ve içerisine extra olarak tanımlamış olduğunuz claims bilgilerine göre machine key’lere bakılarak hash’lenir. Token’ı resource’larınızı kullanacak olan client tarafında tutmalısınız. Token tarzı işlemler için db bazlı bir yerde tutmanızı önermem çünkü çok fazla ihtiyacınız olacak ve her seferinde db’ye erişmek size ek bir maliyet getirecektir. 3. sorunuza gelecek olursak, her servis çağrınızda token apinize gitmeyeceksiniz. Normal resource’larınızın bulunduğu api’de owin’i implemente ettiğinizde token expire süresine veya token key’in olup olmadığına göre orada da kontrol edilmektedir zaten.

      • Oğuz Oğuz

        Gökhan bey merhabalar. Öncelikle cevabınız için teşekkür ederim. Beki daha önce soruldu belki sorulmadı bilmiyorum. Bir sistem tasarlıyorum. Bir binaya girişte kimlik sorulacak. Ok. Token ile bu işi yaptık. binaya giren herkesten kimlik bilgisini aldık.
        2. olarak bina içindeki her odaya girişte bir kimlik kontrolü daha yapmam lazım. Kapıdan her giren o odaya girmeye yetkili olmayabilir. Yetkisi olsa yada olmasa bile benim x kişisi y odasına girdi bilgisini loglamam gerekli. Bu durumda Token üstünde geçerli kişiyi bulursam işimi görür diye düşünüyorum.

        Sorum
        1. Bu bilgiye nasıl erişirim?
        2. sizin önerebileceğiniz daha farklı bir yapı olur mu? Odaların dinamik olarak sayı ve yetkisinin değişmesi unsurunu göz önünde bulundurursak…

        • Merhaba kullanıcı bilgilerine daha önceki yorumlarda da cevapladığım gibi “System.Web.Http namespace’i altında bulunan User context’i üzerinden ulaşabilirsiniz”

  19. Kerem Akbal Kerem Akbal

    Öncelikle örnek için teşekkür ederim ancak uygularken bir hata ile karşılaştım.

    using AspNetWebAPIOAuth.OAuth.Providers;

    satırında Provider assembly’sini kabul etmiyor, bahsettiğiniz paketler yüklü ancak build hatası alıyorum.

    • sertunc sertunc

      OAuth klasörü ve onun içinde de Providers klasörü olmalı sanırım

  20. Özcan Özcan

    Merhaba,

    Hocam, birkaç sorum var. Beni bilgilendirebilirseniz sevinirim.

    1 – Dikkatimi çekti. identity.AddClaim(new Claim(“sub”, context.UserName)); ifadesinde “sub” ne anlama geliyor. Birşeyin kısaltılması mı.

    2- Asıl sorum şu; giriş yapılırken oluşturduğumuz bilgilere diğer metodlardan nasıl erişeceğiz. Örneğin kullanıcı giriş yaptıktan sonra kullanıcının mail adresini, adını soyadını da yükleyip sonraki fonksiyonlardan erişmek istiyorum. ,Aşağıdaki sayfada claim okuması gösterilmiş ancak Foreach ile tüm claim’leri listeleyince claimtype alanı hepsi için http://www.w3.org/2001/XMLSchema#string görünüyor.

    https://msdn.microsoft.com/en-us/library/ee517271.aspx

    public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
    bool kullaniciKontrol = KullaniciKontrol(context.UserName, context.Password);
    if (!kullaniciKontrol)
    {
    context.SetError(“invalid_grant”, “Kullanıcı adı veya şifre yanlış.”);
    return Task.FromResult(null);
    }

    var identity = new ClaimsIdentity(context.Options.AuthenticationType);
    identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
    identity.AddClaim(new Claim(ClaimTypes.Gender, “Erkek”));
    identity.AddClaim(new Claim(“Sirket”, “Deneme Şirketi”));
    identity.AddClaim(new Claim(“sub”, context.UserName));
    context.Validated(identity);
    return Task.FromResult(null);
    }

    Okuma işlemini de şu şekilde yapıyorum.

    [HttpGet]
    [Authorize]
    public List Liste()
    {
    var identity = (ClaimsIdentity)User.Identity;
    IEnumerable claims = identity.Claims;

    foreach (Claim claim in claims)
    {

    sonuc.Add(“claim.Value: ” + claim.Value);
    sonuc.Add(“claim.ValueType: ” + claim.ValueType);
    }
    return sonuc;
    }

    3 – Son sorum da LOGOUT / SIGNOUT işlemini nasıl yapabiliriz veya belli bir ticket i nasıl sistemden remove edebiliriz.

  21. Özcan Özcan

    –DÜZELTME–
    Hocam,

    önceki mesajımdaki 2.soruyu görmezden gelin.
    sonuc.Add(“claim.ValueType: ” + claim.ValueType); ifadesinde ValueType yazmışım oysa sadece Type yazılmalıydı. Gözden kaçmış.

    Şimdi sadece 3 solu sorum için desteğinize ihtiyacım var. LOGOUT işlemini nasıl yapabiliriz veya önceden oluşturulmuş bir token i nasıl geçersiz yapabiliriz.

    • Merhaba, daha öncede cevapladığım gibi: “bu tarz session’ları sizin tracklemeniz gerekmektedir. API stateless olduğu için görevi sadece geçerli bir süreye sahip token üretmektir. Handle işlemini unique bir id kaydedip o id üzerinden siz takip edebilirsiniz, logout olduğunda farklı unique bir değer atamak gibi vb. çözümler düşünebilirsiniz. Aktif olmadığı durumlarda ise zaten token expiry olacaktır.”

  22. Serhan erturk Serhan erturk

    Merhabalar benim size bir sorum olacak isin icinden cikamaz haldeyim:)
    Requesti atip tokenimizi aldik burada sorun yok. Fakat kullanici sifresi degistiginde veya rol degistiginde degismeden once aldigi token yine aktif oluyor.bunun onune nasil gecebiliriz?

    • Merhaba, bu tarz session’ları sizin tracklemeniz gerekmektedir. API stateless olduğu için görevi sadece geçerli bir süreye sahip token üretmektir. Handle işlemini unique bir id kaydedip o id üzerinden siz takip edebilirsiniz, logout olduğunda farklı unique bir değer atamak gibi vb. çözümler düşünebilirsiniz. Aktif olmadığı durumlarda ise zaten token expiry olacaktır.

  23. Şegi Şegi

    Eline sağlık panpa sayende owin i kullandım

  24. solugan solugan

    Kardeşim çok teşekkürler paylaşım için bir şey soracağım ben bu işlemi postman da gerçekleştirdim fakat browser da apinin get metodunu çağırdığımda {“Message”:”Authorization has been denied for this request.”} mesajını alıyorum.Bunu webde de getirebilmem için ne yapmam gerekir bir açıklarmısın? Teşekkürler.

  25. onur onur

    Merhaba Gokhan Bey,

    Hem bu yaziniz hem de refresh token kullanimi yaziniz icin cok tesekkurler. Adeta hayat kurtardiniz

    Iyi Calismalar

  26. Fatih Fatih

    Merhaba
    public override async Task GrantResourceOwnerCredentials
    ve
    public override async System.Threading.Tasks.Task ValidateClientAuthentication
    Kısımlarında await kullanılmadığı için altını yeşil olarak çiziyor.
    yoğun kullanıcı kitlesine sahip uygulamalarda sorun yaratırmı?

  27. Alp Alp

    Merhaba Gökhan,

    Bu değerli yazın için çok teşekkürler.

    Android uygulamam için Web API geliştirdim ve Auth sistemini senin bahsettiğin şekilde yaptım.

    Sorun şu ki , Web API’mdeki her metod Auth gerektiriyor ve kullanıcılarım uygulamamı kullanınca bazen Web API çalışmaz hale geliyor…

    Böyle olunca sunucudan IIS ‘ e girip siteyi yeniden başlatıyorum ve sorun düzeliyor…

    Sence bunun çözümü nedir ? Token sistemi IIS ‘ i yoruyor olabilir mi ?

    Uygulamam çalışırken metodlarımda genelde veri tabanımdan 30-50 satırlık veri çekiyor (Uygulama başladığında bunun gibi 3,4 istek yapıyor… , bu isteklerle de alakalı olabilir mi ?)

    İyi çalışmalar…

    • Merhabalar, öncelikle ben teşekkür ederim.

      Sorunuza gelecek olursak eğer API method’larınızın authentication gerektiriyor olmasının ve yük altında “çalışmaz bir hale gelmesi” konusu, ne API ile nede auth işlemleri ile alakalı olduğunu düşünmüyorum. Burada kodlamanızdan kaynaklı bottleneck’leri herhangi bir APM tool’u ile adresleyebilirsiniz. Tahminimce memory leak yaratan bir kod bulunmakta. Ezbere konuşmak zor bu tarz işlemler için.Eğer prod ortamlarınızda newrelic gibi apm tool’ları var ise, bir performans raporu almanızı önerebilirim.

      • Alp Alp

        Tekrardan merhaba Gökhan,

        İlgin için çok teşekkürler.
        Kodlarımın tamamını inceledim ve her bir API çağrımda MySql bağlantısı oluşturduğumu ve sonradan birçoğunun MySql bağlantılarını kapatmadığımı farkettim , tamamen kodları yeniden düzenleyince bi sorun olmadı.

        Dediğin araçları kullanıp temiz bir analiz yapamadım ama çalışıyor şuanlık 😀

        İyi çalışmalar…

  28. Burak Burak

    Merhaba,
    Aşağıdaki kodları tam olarak anlayamadım UserName ve Password ne amaçla kullanılıyor Sqlconnection satırında mssql servera bağlanırken ki gibi tek seferlik bir username ve password mu yoksa benim database serverıma bağlanıp User tablomda ki kullanıcılar mı ?

    if (context.UserName == “Gokhan” && context.Password == “123456”)
    {
    var identity = new ClaimsIdentity(context.Options.AuthenticationType);

    identity.AddClaim(new Claim(“sub”, context.UserName));
    identity.AddClaim(new Claim(“role”, “user”));

    context.Validated(identity);
    }

    Şimdiden Teşekkürler,

    • Merhaba o kısım kullanıcılarınızın login sırasında token alabilmeleri için gerekli olan standart username, password bilgileridir. Tabi bu kısmı kendinize göre tailor bir business yapabilirsiniz.

  29. Hakan ZOR Hakan ZOR

    Güzel uygulama olmuş teşekkürler. Şöyle bir problemim var. Benim uygulamamda login olurken 3 ayrı parametre alıyorum. Burada sadece kullanıcı adı ve şifreye göre yapılmış.

    Kullanıcı Adı, Şifre, TC

    Ne yapmam lazım ?

    • Merhaba, additional parametreleri “OAuthGrantResourceOwnerCredentialsContext” üzerindeki Request property’sinden erişebilirsiniz. Örneğin:
      var requestForm = await context.Request.ReadFormAsync();
      requestForm[“additionalParameter”] gibi.

      Saygılar.

      • Yunus Emre Yunus Emre

        Merhaba,

        Öncelikle faydalı yazınız için çok teşekkür ederim.

        Sistemimde user authentication’a ek olarak, application authentication da olacak. Dolayısı ile username – password ikilisinin yanında clientId (bu zaten context’te mevcut) ve client password’e ihtiyacım olacak.

        Client Password bilgisini yukarıda bahsettiğiniz Additional Parameters’da mı almam mantıklı yoksa başka bir yol mu önerirsiniz application authentication için ?

        • Merhaba,

          Client doğrulaması için client id ve client secret gibi bilgiler kullanılmakta standart olarak. Validation işlemini ise “ValidateClientAuthentication” method’unda gerçekleştirebilirsiniz.

          • Yunus Emre Yunus Emre

            ClientId’yi OAuthGrantResourceOwnerCredentialsContext ve OAuthValidateClientAuthenticationContext nesnelerinin altında görebiliyorum ama Client Secret property’sini göremedim. Onu nereden almak gerekiyor ?

          • Client secret’a neden ihtiyacınız var?

          • Yunus Emre Yunus Emre

            Spesifik olarak Client secret’a ihtiyacım yok aslında. Benim client id ve clientpassword ikilisine ihtiyacım vardı. Client Id zaten context’te mevcut, Header’a da clientpassword’u ben ekleyerek çözmüştüm ama siz client secret yazınca header’a eklediğim clientpassword alanının yerini tutuyor sanıp o yüzden sormuştum. Sanırım yanlış anlamışım kusura bakmayın 🙂

  30. Efe ÖZYER Efe ÖZYER

    Hocam tekrar merhabalar, basic Asp Net Web Api 2 projesi ile bir proje tamamladım ancak bilemediğim bir nedenden dolayı access_token belli kullanıcılarda çok uzun bir string oluyor. Daha sonra token’i header’a ekleyip post ettiğimde ise ;

    HTTP Error 400. The size of the request headers is too long.

    Hatasını alıyorum. Sunucu tarafında bunu çözemedim IIS’de internette geçen tüm ayarları denememe rağmen bu hatayı vermeye devam ediyor. Token uzunluğunu optimize edebilir miyim?

      • Efe ÖZYER Efe ÖZYER

        Evet devam ediyor, Jwt token’a geçemyi düşünüyorum ne dersiniz?

        • Merhaba, JWT’nin çözüm olacağını düşünmüyorum. Token string’inin çok uzun olmasının sebebi token içerisine neler ekliyorsunuz? Claim’ler vb? Nasıl bir data koyduğunuz ile alakalı bir durum bu.

  31. Merhaba. Öncelikle kitabınızı okumaya yeni başladım, gerçekten çok güzel bir kaynak. Ben aşağıdaki gibi web servis fonksiyonuna rol tabanlı erişim izni vermek istiyorum. Bunu nasıl yapabilirim?

    [Authorize(Roles = “Admin”)]
    public List List()
    { /*Komutlar*/ }

    Şimdiden teşekkürler.

    • Selamlar, bu işlemleri claim’ler ile yönetebilirsiniz. Token’ı ürettiğiniz yerde kullanıcının claim’ine rolleri set edebilirsiniz. Kolay gelsin.

      • İlginiz için teşekkür ederim. Peki oluşturulan token bilgileri nerede saklanıyor? LoadBalancer’lı bir mimariyi düşündüğümüzde farklı makinalarda oluşturulan tokenları diğer makinalar üzerinde oturum açılmaya çalışıldığında oturum açılır mı? Eğer oturum açılmazsa böyle bir senaryoya nasıl bir çözüm bulunabilir?

        • Token bilgileri herhangi bir yerde persist edilmiyor. MachineKey bilgileri ile encrypt ediliyor. Load-balancer kısmında bir karışıklık var sanırım. Identity server’ınız lb arkasında ise ve farklı makineler da ise, aynı farmda olabilmeleri ve aynı key’leri üretebilmeleri için machinekey bilgilerinin de aynı olması gerekmektedir. Identity server’ı cluster olarak kurduğunuzda da böyle bir şeye gerekte kalmayacaktır. Eğer identity server yerine custom bir api üzerinden owin context’i ile key’leri siz üretiyorsanız, ozaman ihtiyaç duyacaksınız. Kolay gelsin.

  32. kadir kadir

    Merhaba, adımları uyguladığımda hatta sizin paylaştığınız uygulamayı indirip onda test ettiğimde
    The requested resource does not support http method ‘POST’. hatası alıyorum

    • kadir kadir

      Çözüldü teşekkür ederim. Get işlemini /token yerine yine apinin adresinde denemişim

  33. kadir kadir

    Merhaba,
    Makalede bahsettiğiniz token alma ve veri çekme ile ilgili yapıları bir c# windows forms uygulamasında kullanılacak şekilde örneklendirebilir misiniz? Yani orderscontroller tarafından sağlanan verilere windows forms ile ulaşmak istiyorum ve aynı zamanda oAuth kullanmak istiyorum.

    • Merhaba, istediğiniz platform’da kullanabilirsiniz. Tek yapmanız gereken REST request’lerini nasıl gerçekleştirebileceğinize bakmanızdır. RestSharp kütüphanesi bu konuda size yardımcı olabilir. İyi günler.

      • kadir kadir

        Çok teşekkür ederim. RestSharp ve Postman’deki Generate Code Snippets işimi gördü.

  34. Murat Murat

    Merhabalar,

    Çok güzel bir örnek olmuş. Token pat ile ilgili bir sorum olacaktı.
    TokenEndpointPath = new Microsoft.Owin.PathString(“/token”)

    tokenendpoint pathi “/wp/token” şeklinde nasıl tanımlayabiliriz. Yada böyle bir tanımlama yapabilir miyiz.

    Teşekkürler.

  35. Mehmet Ali Mehmet Ali

    Merhaba makeleniz için teşekkürler. Anlayamadığım bir nokta var. Makelenizde;

    “Authorization Server bu bilgileri doğrulursa, client’a bir Access Token Http Response’u döner.” ve
    “Client artık erişmek istediği servislere, elde etmiş olduğu Access Token’ı Http Request’in Authorization Header‘ına ekleyerek erişim sağlar.” diye yazmışsınız.

    Toke’nin Headera eklenmesiyle yapılan isteklerde, sistem temel olarak token doğrulamasını nasıl yapıyor? Yani, oluşturularak Clienta göndereilen Token aynı zamanda server tarafında tutuluyor mu? Tutuluyorsa hangi logic ile? Cache mi database mi?

    • Merhaba tutulma işlemi bulunmamakta. Her şey on the fly olarak gerçekleşiyor. Token alınırken veriler encrypt ediliyor, daha sonrasında ise decrypt işlemi gerçekleşiyor ve bu işlem sırasında da expire time’ları da göz önünde bulunduruluyor. Token ile gelinen endpoint üzerinde owin kurulu ise kendisi bu pipeline’ı otomatik olarak işletiyor.

      Saygılarımla.

  36. İlker Yüksel İlker Yüksel

    Merhaba,
    Çok bilgilendirici bir yazı olmuş teşekkür ederim.
    Biraz temel kısımda takılmış olabilirim ama şu kavramlarda sanırım bir sıkıntım var. Bildiğim kadarıyla;
    Authentication : Kullanıcının siteme giriş yapmasını kontrol eden sistem
    Authorization : Giriş yapmış kullanıcının ilgili işleme erişimini kontrol eden sistem
    Yazı başlığında ve konusunda authentication işlenmesine rağmen neden Authorize attribute’ü kullandık ?

    Aşağıdaki makalede Authorize attribute’ünü Authorization kısmında kullanmışlar bu yüzden biraz karıştırdım sanırım
    https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-and-authorization-in-aspnet-web-api

    • Merhaba evet kavramlar doğru. Attribute konusuna gelirsek, authentication client’ın makinaya erişmesine bakarken, authorization ise ilgili kullanıcının gerçekleştirmek istediği request’e izni var mı yok mu gibi konulara bakmaktadır. Pipeline’a baktığınızda ise, en son AuthorizationFilter’lar gelmektedir. Burada ise ilgili scope ve claim’ler doğrultusunda kullanıcılara işlem yaptırılabilmektedir. Bu sebeple en authorize attribute’ü kullanılmaktadır.

  37. Ali Ali

    merhaba,

    token üretirken grant_type = password yerine grant_type = client_credentials olarak token üretmek istersem ne yapmam gerekiyor ?

    • Merhaba, herhangi bir şey yapmanıza gerek yoktur. Client credentials flow’u ile ilerlemek istiyorsanız grant_type’ı set edip, client id ve client secret ile devam etmelisiniz.

  38. golbasi golbasi

    hocam kolay gelsin, kafama şey takıldı, şimdi sunucu tarafında üretilen token keyleri, acaba sunucuda bir yerde depolanıyor mu, zira token kullanarak istek geldiğinde karşılaştırmayı nasıl yapacak?

    • Merhaba, depolanmamaktadır tüm işlemler on the fly olarak hesaplanmaktadır. Bunu daha önceki yorumlarda cevaplamıştım. Token’lar machineKey’e göre encrypt ve decrypt edilmektedir.

  39. hikmet hikmet

    Merhaba,

    Token’ı tek kullanlık nasıl yapabiliriz ? Yani oluşturulan her token yalnızca 1 kere kullanılabilsin. Her method çağrıldığında farklı token istesin

    • Merhaba neden böyle bir şeye ihtiyacınız var? Token’ın kullanım amacı bu şekilde olmamalı OAuth çatısı altında. Eğer method based credentials’a ihtiyacınız varsa da, bunları scope’lar ve claim’ler ile yönetebiliyor olmalısınız. Saygılar.

  40. Arda Arda

    Hocam saygılar. Bir mobil projem var, verileri servisten çekiyorum. Ben token olayını şu şekilde yaptım. Client servise kullanıcı adı parola ile geliyor, bilgiler doğruysa o kulanıcıya token olarak guid atıyorum ve sqlservere kaydediyorum(atadığım bu tokeni cliente result ediyorum oda kendi hafızasına alıyor.). Daha sonra client sorgulama ekranına gelip sorgulama parametrelerinin yanında birde tokeni yolluyor. servis bu tokene sqlserverdan bakıp geçerli oturum olup olmadığına bakıyor oturum geçerliyse sorgulama sonucunu döndürüyor. doğru değil veya süresi dolmuşsa hata dönderiyirum. ben sistemimi bu şekilde kurdum. Sizin bu anlattığınız sisteme geçsem mi diye düşünüyorum. Sizce geçmelimiyim. Benim sistemimden farkı daha güvenlikli olmasımı yoksa benim sistemimde aynı işi yapıyor mu?

    • Arda Arda

      Birde ben kendi sistemimde: kullanıcı bir kere girip token aldıktan sonra sistemden çıkıp tekrar girerse veya başka bir cihazdan oturum açarsa eski oturumu iptal ediyorum. bunu bu sistemde şöyle yapmayı düşündüm:
      /token den kullanıcıya tokeni return ettim aynı zamandada sqlserverde log tabloma bu tokeni kaydettim. daha sonraki girişlerde aynı kullanıcı tekrar girerse eski oturmu iptal edeceğim.

      sizce mantıklımı?

      • OAuth standartlarında bu tarz bir işlem yapabilmek standart dışı olarak ancak, custom bir şekilde gerçekleştirebilirsiniz. OAuth için token’ın bir expire date’i vardır ve expire date’i geldiğinde sona erer. Eğer business’ınız bunu gerektiriyorsa tek bir oturumu, custom olarak gerçekleştirmelisiniz.

    • Merhaba, token’ları persist etmeniz çok efektif olmayacaktır. OAuth 2.0 standartlarında token’ları bearer olarak on the fly yapmanız sizin yararınıza olacaktır. Saygılar

  41. Hikmet Hikmet

    Merhaba, Token dönerken yanında farklı bir bilgi daha döndermek istiyorum(örn kullanıcıId) nasıl dönderebilirim.

    • Merhaba bu bilgileri zaten claim olarak set edebiliyorsunuz, makaledeki gibi “new Claim(“sub”, context.UserName)” gibi. Saygılar

  42. Hikmet Hikmet

    identity.AddClaim(new Claim(“UserId”, “12345”));

    olarak eklesem bile Json dönüşünde sadece access_token,expires_in ve “bearer” bilgileri görüüyorum. Burada UserId ninde dönmesini istiyorum. Nasıl yapabilirim?

    • Merhaba, claim üzerine set ettiğiniz bilgileri ilgili client üzerinden kullanıcı validate olduktan sonra, System.Web.Http namespace’i altında bulunan User context’i üzerinden ulaşabilirsin. Saygılar.

  43. ahmet ahmet

    Gökhan merhaba, Yazdığım bir api servisine hangi domainlerden istek geldiğini nasıl görebilirim.
    Amacım api’i kullanan siteleri tespit etmek. ajax ile gelen isteklerde Request.UrlReferrer den görebiliyorum ama mesela Asp.Net Mvc de backend den httpclient ile yaptığım bir istekte UrlReferrer değeri boş geliyor.

    • Merhaba, eğer null’sa yapılabilecek bir şey var mı bilemiyorum. Eğer probleminiz farklı domain’lerden api’ınızın call edilmesi ise, cors ayarlarını yapmanızı tavsiye ederim. Bir diğer çözüm ise urlreferrer kontrolü yapmanız olacaktır null mı değil mi gibi. Kolay gelsin.

  44. metin metin

    Merhaba, öncelikle authentication konusundaki aydınlatıcı fikirleriniz için teşekürler.
    Ben örnek projenizi indirip postman tool ile sıkıntısız işlemler yaptım.
    Yardım istediğim konu postman(bir metoda authenticate olup ticket alma sonra bu token ile başka metod çağırma) ile yaptığımız işlemleri asmx web serviste backened olarak nasıl yapabilirim. Biraz denedim ama işin içinde çıkamadım.
    token ile asmx web servisi authentication örnek bir kod gösterebilir misiniz
    Teşekürler..
    Saygılarımla

  45. mamacita mamacita

    Her şeyi teker teker ve sade bir dille açıklamışsınız, teşekkürler.

  46. Merhaba, öncelikle makale için teşekkür ederim. Güzel olmuş. Ajax post ile token alma konusunda sıkıntı yaşamıyorum fakat ajax post güvenli gelmediği için post işlemini controller içerisinden yapmaya çalıştığımda bir türlü context parametrelerini geçemedim.

    https://i.hizliresim.com/ZZ8YX0.jpg

    • Merhaba, size tavsiyem restsharp gibi rest call wrapper library’lerini kullanmanız olur. 🙂

  47. Anlatım gayet güzel olmuş eline sağlık. Kurulumu yaptım web api uygulamam için postman üzerinden testini gerçekleştirdiğimde token alma ve bu token ile request gönderme işlemleri başarıyla çalıştı. Ancak tek bir problemim var jquery ajax ile token almak için post işlemi gerçekleştirdiğimde 404 (Not Found) ve No ‘Access-Control-Allow-Origin’ header is present on the requested resource. hataları alıyorum. Web api çağırılarımda da aynı hatayı alıyordum httpResponseMessage.Headers.Add(“Access-Control-Allow-Origin”, “*”); ekleyerek çözmüştüm. Ancak oauth ‘da bu yeterli olmadı. Çözüm için öneriniz var mı.

    • Merhaba öncelikle “GrantResourceOwnerCredentials” implemente ederken oradaki CORS ayarlarını set ettiniz mi?

  48. Ayşe Sayarı Ayşe Sayarı

    Merhabalar, örneklendirmeleriniz ve makaleniz için çok teşekkür ederiz. Gerçekten çok makbule geçti ve fayda gördüm. Yalnız bir konuda size danışmam gerekti. Örneğinizde bahsettiğiniz yetkilendirmeleri yaparken metod başına [Autorize] özniteliğini yerleştiriyorsunuz.

    Ben simple membership kullanmıyorum ve kendi üyelik sistemim var. Metodun başına koyduğunuz [Authorize] özniteliği membership için mi yoksa OAuth 2.0 nin bir parçası mı, açıkçası tereddütte kaldım.

    Bu konuda bir fikriniz var mıdır ? Hazır membership kullanmıyorsak, OAuth 2.0 yi implement edebiliyor muyuz projemize ?

    Teşekkürlerimi sunarım.

    Ayşe

    • Merhaba, Authorize attribute’ü “System.Web.Http” içerisinden gelmektedir. Ister OWIN ile OAuth imp. kullanabilirsiniz, isterseniz de eğer simple membership provider kullanıyorsanız onunlada kullanabilirsiniz. Teşekkür ederim.

  49. Emre Emre

    Merhaba , username password e ek olarak bir parametre daha göndermek istiyorum acaba ne yapmam gerekli anlatım için teşekkürler

    • Merhaba, additional parametreleri “OAuthGrantResourceOwnerCredentialsContext” üzerindeki Request property’sinden erişebilirsiniz. Örneğin:
      var requestForm = await context.Request.ReadFormAsync();
      requestForm[“additionalParameter”] gibi.

      Saygılar.

  50. Uğur Uğur

    Merhaba,
    Token oluşturulduktan sonra kullanıcı şifre değişikliği yada kullanıcı yetkilerindeki değişikliklerde daha önce alınan token ı nasıl iptal edebiliriz?

    • Merhaba, bu konuda en çok sıkıntı çekilen nokta burası açıkcası. Çünkü token’ları store etmediğimiz için on the fly hesaplandığı için bu tarz işlemler malesef ki mümkün değildir. Bu işlemin best practice’i şudur diyemiyeceğim. Manuel işlemler yapıp, token’ı kontrol etmemiz veya expire sürelerini optimum süreler vererek, tekrardan yeniletmeye zorlatmalıyız.

  51. Yusuf Şahlan Yusuf Şahlan

    merhaba. sadece access_token değerini döndürmenin bir yolu var mı? sadece verilen token değerini döndürmek istediğimde ne yapmalıyım?

    • Merhaba bu konudaki tam isteğiniz nedir acaba? refresh token olmadan mı?

  52. Demir Demir

    Hocam makaleyi güncelleseniz ne güzel olur. Mesela bu oluşturduğumuz tokenler nerede tutuluyor?
    Rolleme nasıl yapılır? İyi çalışmalar

    • Merhaba, evet vakit bulduğumda güncellemeyi planlıyorum biraz daha detaylı, OAuth2 standartlarına uygun vb. bir şekilde.
      Not: Tokenlar on the fly üretilmektedir, bir yerde store edilmiyor.

  53. gokhan gokhan

    Selamlar,
    Hazirladigim sistemde 2 islem mevcut. Bir normal kullanicilarin kullandigi panel, digeri de entegre olup web api ile veri cekecek olan kullanicilar. Normal kullanicilar icin mvc5 icerisinde default gelen Owin Authentication kullaniyorum. Api icin de makalede anlattiginiz islemleri yaptim token degerimi aldim fakat token parametresi gelmemisse ya da username / password bilgisinden biri yanlissa Account/Login sayfasina yonlendirme islemi yapiyor.

    Authentication islemlerinde normal kullanici ile api kullanicisini nasil ayirabilirim? Yani sormak istedigim normal kullaniciya View ile sonuc dondurmek isterken api erisimlerinde json veri basabilmek istiyorum bunu basaramadim. Konuyla ilgili fikir verebilirseniz sevinirim.

    • Merhaba, normal şartlarda ayırmamanız, yani ortak bir authentication işlemlerini yönettiğiniz bir API/IdentityServer olmalı ve her iki kullanıcı da login işlemleri için geçerli token’larını oradan almalılar. Yetkileri ise claim’ler le yönetmelisiniz. Sizin şuanki case’iniz de ise, User claim’i içerisine ayırt edebileceğiniz bir property set edebilirsiniz.

  54. Rıfat Rıfat

    Merhaba,
    grant_type=password ile deneme yaptığımda GrantResourceOwnerCredentials fonksiyonuna hiç girmiyor ve “error”: “unsupported_grant_type” hatası alıyorum. Hatayı nasıl giderebilirim?
    İyi çalışmalar.

  55. Doğan Doğan

    Controller içerisinde mevcut claim in rolünü değiştirmek veya yeni rol eklemek mümkün müdür ? bunu nasıl yapabiliriz yardımcı olabilir misiniz.
    Teşekkürler.

      • Doğan Salman Doğan Salman

        Hocam login işlevinde veritabanındaki bir değerin durumuna göre rol ekliyorum ve daha sonra bu rolü kullanıcı isterse değiştirebiliyor. Bu değişikliği api’de algılamam gerekiyor aksi halde rol kısıtlaması olan hiç bir istek cevap vermiyor.

        • Merhaba, kusura bakmayın geç cevap için, malum yoğunluklar. Öncelikle sormak istediğim şey: neden kullanıcı kendi rolünü değiştirebiliyor? Bu şekilde bir authorization nasıl olabilir ki? Sanki tasarımda bir hata var gibi geliyor bana.

  56. epocha epocha

    Merhabalar.
    Apiyi satın aldığım bir web hostinge upload edip deploy ettiğimde token alabiliyorum fakat.
    api/Orders/List çağrısını ürettiğim tokenle sorguladığımda
    Error – 404.0 – Not Found hatası alıyorum.
    MapRequestHandler- Staticfile gibi bir hata alıyorum.
    Sitede IIS 8.5 kurulu.
    Acaba Api nin config ayarlarında bir şey mi değiştirmek gerekiyor bir fikriniz var mıdır ???

    • Application pool’da ASP.NET 4.0 seçili olduğundan emin misiniz? Eğer seçili ise, ISAPI filter’larına bir göz atınız.

  57. Fatih Fatih

    Ellerine saglik guzel olmus

  58. Yücel Yücel

    Ben android uygulamam için bu şekilde bir webapi olulturdum ve çalıştırdım. Android uygulamamdan bu webapiyi nasıl çağıracağım ve işlemleri nasıl yapacağım? Android tarafı için bilginiz varmı yada yönlendirebileceğiniz bir kaynak ?

    • Bunun için çeşitli rest client’ları mevcut. Genelde en yaygını “OkHttp”, “Volley” var benim bildiklerim. Onun dışında çok bir bilgim yok malesef. 🙂

  59. Arda Can Arda Can

    Merhabalar,

    Yazı için çok teşekkürler detaylı bir anlatım olmuş. Apiyi test etmek için Fiddler,Postman kullanmadan bir asp projesi ile verileri çekebilirmiyiz?
    Elimde örnek kod var ama bir türlü [Authorize] kullanarak çekemedim. Yol gösterirseniz sevinirim.Teşekkürler

    • Merhaba, beğenmenize sevindim. POSTMAN gibi bir tool kullanmadan herhangi bir REST client’ı ile de aynı işlemi gerçekleştirebilirsiniz. Örneğin Restsharp. [Authorize] attribute’ü ile çekme nedir acaba?

  60. mesut mesut

    merhaba
    AccessTokenExpireTimeSpan değerini bir gün gibi bir süre yaptığımda token geçerliliği bu süre olmuyor, bazen 20 bazen 40 bazen 200 dakikada token expire oluyor, bunun sebebi ne olabilir?

    • Merhaba, böyle bir problem ile karşılaşmadım hiç açıkcası. Deploy ettiğiniz (server) ve kullandığınız ortamlardaki “date” formatlarının doğruluğunu kontrol ettiniz mi?

    • mesut mesut

      iis üzerindeki machine keyi statik yapmak gerekiyormuş,

      bir sorum daha var, metot bazlı exprire date belirtebiliyor muyuz?

      • Merhaba token’lar genel olarak bir expire date’e sahip. Method’lar üzerindeki işlem ve yetki kısıtlamalarını claim’ler ile yapabilirsiniz.

    • Aynı sorunu bende yaşadım. Çözümü static bir machine key belirleyiniz.

      Uzak sunucudaki IIS restart olabilir. Özellikle hostinglerde.

      Sorunu çözecektir.

  61. Gökhan Bey Merhaba,

    Makale için teşekkür ederim şimdiden. Emeğinize, bilginize sağlık.

    Bir sorum var benim. Token oluşturduktan sonra expiration’ı 30 gün belirlememe rağmen uzak sunucuda ve local de ortalama 15-30 dk içinde expire oluyor ve token kullanılamıyor.

    Sizce sebebi ne olabilir.

    İyi günler dilerim.

    • Merhaba, bu konuda ezbere birşey diyemem fakat oluşan token’da “expires_in” alanındaki değerini kontrol ettiniz mi? Birde her token’ı valide etme işleminizde expire time’ı üzerinde herhangi bir değişiklik yapıyormusunuz?

  62. Hocam çok başarılı makale olmuş. Ellerine sağlık. Teşekkür ederim

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*