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:
- 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.
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:
using AspNetWebAPIOAuth.OAuth.Providers; using Microsoft.Owin; using Microsoft.Owin.Security.OAuth; using Owin; using System; using System.Web.Http; [assembly: OwinStartup(typeof(AspNetWebAPIOAuth.OAuth.Startup))] namespace AspNetWebAPIOAuth.OAuth { // Servis çalışmaya başlarken Owin pipeline'ını ayağa kaldırabilmek için Startup'u hazırlıyoruz. public class Startup { public void Configuration(IAppBuilder appBuilder) { HttpConfiguration httpConfiguration = new HttpConfiguration(); ConfigureOAuth(appBuilder); WebApiConfig.Register(httpConfiguration); appBuilder.UseWebApi(httpConfiguration); } private void ConfigureOAuth(IAppBuilder appBuilder) { OAuthAuthorizationServerOptions oAuthAuthorizationServerOptions = new OAuthAuthorizationServerOptions() { TokenEndpointPath = new Microsoft.Owin.PathString("/token"), // token alacağımız path'i belirtiyoruz AccessTokenExpireTimeSpan = TimeSpan.FromDays(1), AllowInsecureHttp = true, Provider = new SimpleAuthorizationServerProvider() }; // AppBuilder'a token üretimini gerçekleştirebilmek için ilgili authorization ayarlarımızı veriyoruz. appBuilder.UseOAuthAuthorizationServer(oAuthAuthorizationServerOptions); // Authentication type olarak ise Bearer Authentication'ı kullanacağımızı belirtiyoruz. // Bearer token OAuth 2.0 ile gelen standartlaşmış token türüdür. // Herhangi kriptolu bir veriye ihtiyaç duymadan client tarafından token isteğinde bulunulur ve server belirli bir expire date'e sahip bir access_token üretir. // Bearer token üzerinde güvenlik SSL'e dayanır. // Bir diğer tip ise MAC token'dır. OAuth 1.0 versiyonunda kullanılıyor, hem client'a, hemde server tarafına implementasyonlardan dolayı ek maliyet çıkartmaktadır. Bu maliyetin yanı sıra ise Bearer token'a göre kaynak alış verişinin biraz daha güvenli olduğu söyleniyor çünkü client her request'inde veriyi hmac ile imzalayıp verileri kriptolu bir şekilde göndermeleri gerektiği için. appBuilder.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()); } } }
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:
using Microsoft.Owin.Security.OAuth; using System.Threading.Tasks; using System.Security.Claims; namespace AspNetWebAPIOAuth.OAuth.Providers { public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider { // OAuthAuthorizationServerProvider sınıfının client erişimine izin verebilmek için ilgili ValidateClientAuthentication metotunu override ediyoruz. public override async System.Threading.Tasks.Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context) { context.Validated(); } // OAuthAuthorizationServerProvider sınıfının kaynak erişimine izin verebilmek için ilgili GrantResourceOwnerCredentials metotunu override ediyoruz. public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context) { // 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 == "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); } else { context.SetError("invalid_grant", "Kullanıcı adı veya şifre yanlış."); } } } }
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:
using System.Collections.Generic; using System.Web.Http; namespace AspNetWebAPIOAuth.Controllers { public class OrdersController : ApiController { [HttpGet] [Authorize] public List<string> List() { List<string> orders = new List<string>(); orders.Add("Elma"); orders.Add("Armut"); orders.Add("Erik"); return orders; } } }
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:
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:
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.
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.
Emeğine sağlık çok faydalı oldu
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.
Güzel ve anlaşılır olmuş. Anlatımına sağlık
Yazı için teşekkürler. Postman kullanmadan nasıl ajax isteği gönderebileceğimizi anlatabilir misiniz?
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?
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?
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.
Replace(parent.comment,”olacağı konusundayım.”,”olacağı kanısındayım.”);
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 token uygulamasını birden fazla sunucuda çalıştırdığım taktirde. A sunucusunda aldığı tokenı B sunucusunda nasıl doğrulatabilirim.
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?
Ç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,
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?
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
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.
Kitabınız çıktı mı acaba
ASP.NET WEB APİ KİTABINIZ NE ZAMAN ÇIKIYOR
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.
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 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 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..
Ö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.
OAuth klasörü ve onun içinde de Providers klasörü olmalı sanırım
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.
–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.
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?
Eline sağlık panpa sayende owin i kullandım
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.
Merhaba Gokhan Bey,
Hem bu yaziniz hem de refresh token kullanimi yaziniz icin cok tesekkurler. Adeta hayat kurtardiniz
Iyi Calismalar
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ı?
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…
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,
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 ?
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?
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.
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
Çözüldü teşekkür ederim. Get işlemini /token yerine yine apinin adresinde denemişim
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.
Gökhan Hocam saygılar,
tek kelime ile excellent 🙂
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.
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,
Ç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,
token üretirken grant_type = password yerine grant_type = client_credentials olarak token üretmek istersem ne yapmam gerekiyor ?
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,
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
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?
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ı?
Merhaba, Token dönerken yanında farklı bir bilgi daha döndermek istiyorum(örn kullanıcıId) nasıl dönderebilirim.
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?
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, ö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
Her şeyi teker teker ve sade bir dille açıklamışsınız, teşekkürler.
[…] Kaynak: Asp.Net Web API – Token Based Authentication […]
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
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ı.
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 , username password e ek olarak bir parametre daha göndermek istiyorum acaba ne yapmam gerekli anlatım için teşekkürler
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. 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?
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
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,
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.
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.
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 ???
Ellerine saglik guzel olmus
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 ?
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
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?
iis üzerindeki machine keyi statik yapmak gerekiyormuş,
bir sorum daha var, metot bazlı exprire date belirtebiliyor muyuz?
Aynı sorunu bende yaşadım. Çözümü static bir machine key belirleyiniz.
Uzak sunucudaki IIS restart olabilir. Özellikle hostinglerde.
Sorunu çözecektir.
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.
Hocam çok başarılı makale olmuş. Ellerine sağlık. Teşekkür ederim
Merhaba,
Username ve password kısımlarını, asp.net Membership ile entegre edebilirmiyiz ?
Web Api’ye sisteme üye olanlar erişsin istiyorum, örneğin windows form application üzerinden login bilgilerini girdikten sonra web api’de doğruluğu kontrol edildiği taktirde diğer form ekranı açılsın veya mobil application tarafı içinde öyle.
Gökhan Bey merhaba,
Token alma işlemi IIS te ve ISSExpress te localde çalışıyor. Fakat restapi yi Reseller üzerinde hosta publish ettiğimde, Token almak isteğimde, “unsupported_grant_type” hatası alıyorum.
Diğer controllerlar ([Authorize] kaldırdığımda ) normal şekilde çalışıyor ama. Her şeyi denedim düzelmedi. Sebebi ne olabilir sizce ?
Teşekkür ederim.
Merhaba,
Cors ayarlarını set ederken username ve password verilerini programın içinde belirtiyoruz.
Bu verilerin veri tabanından gelmesi için ne yapmamız gerekiyor. Yani her kullanıcı kendi bilgilerini girerek token almasını nasıl sağlayabiliriz. Teşekkür ederim.
Merhaba,
SimpleAuthorizationServerProvider.cs sınıfında aşağıdaki satırda UserName ve Password tanımlamışsınız.Bende ise apikey ve secretkey mevcut bu iki kod birleştirip(https://www.base64encode.org sitesinde iki kod beraber girdiğimde elde ediyorum) bearer token oluşturuyorum. Username ve password yerine apikey ve secret key girdiğimde ise hata ile karşılaşıyorum.Konu ile ilgili yardımcı olabilir misiniz?
// 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 == “Gokhan” && context.Password == “123456”)
Güzel faydalı bir paylaşım olmuş. Teşekkür ederiz. token kısmına illa bir süre vermek gerekir mi. ? Vermezsek bir sıkıntı yaratır mı. ? Saygılar.
öncelikle emeğinize sağlık, storedprocedurli model katmanına tanımladım ve conrolleri oradan gerçekleştiriyorum. farklı platformlar içinde bir api hazırladım ve ajaxla veri çekeceğim. model olarak ve storedprocedurum hazır autorization ile databasden login kontrolü nasıl yaparım ..teşekkürler
Hocam merhaba, mobil uygulama için token based authentication yöntemi ile yazdığımız serviste logout işlemini nasıl yapabiliriz, yani bearer token’ının aktifliğini nasıl sonlandırabiliriz kullanıcının çıkış yaptıktan sonra yetkisi olmayan yerlere girmesini engellemek için doğru yol nedir ?
Gayet güzel bir yazı, teşekkürler!
Öncelikle bu güzel paylaşım için teşekkürler. Yıllar olmuş ama hala faydalı insanlara. Tek eklemek istediğim şey, proje/properties/web/project Url kısmında, https.. ile başlayan url nin http ye döndülmesi gerekmekte. Neden bilmiyorum ama öyle çalışıyor postmanda.
Yazı gayet anlaşılır olmuş aslında elinize sağlık. Peki hali hazırda bulunan bir apiye bearer token ile baglanmak istesek nasıl uygulayabiliriz? Bu konuda bir örnek üretebilirmisiniz?
Merhabalar Gökhan Bey,
Ben bu sistemi kullanarak bir api authorize işlemi yaptım fakat merak ettiğim bir konu var.
Ben bir api yazarak ve bu api methoduna giriş yapan token ı gönderip o token in ne kadar süresi kaldığı bilgisine ulaşabilir miyim? aslında amacım aslında kişinin ne kadar süresi kaldığını görmek. bunu çerezlere vs kaydederek değilde direk api çağırır gibi çağırıp görebiliyor muyuz?
hocam yazilarinizi severek okuyorum cok sagolun. gecenlerde bir projede resimi formfile seklinde dondurdum apide goruyorum. ancak resimleri liste halinde bir kac resim donunce gorunteleri alamiyorum bununla alakali ornek bulabilecegim bir iceriginiz var mi baktim ancak goremedim veya bir tavsiyeniz olur mu? simdiden tesekkurler kolay gelsin 🙂
Emeğine sağlık, hatasız çalıştı çok sağol.