İçeriğe geç

ASP.NET Core Kimlik Doğrulama (Identity Server 4)

Giriş
Kimlik doğrulama, bir uygulamadaki verilerin gizliliğini sağlama noktasında ihtiyaç duyulur. Projelerdeki bazı kaynakları sadece belirli kullanıcıların erişimine açmanız olasıdır. Web uygulamalarında olduğu gibi mobil veya javascript tabanlı uygulamalarda da ihtiyaç duyulabilir. Günümüzdeki çoğu uygulama tipleri genelde aşağıdaki gibi görünmektedir ve buradaki her bir talep(request) için bir yetki kontrol sistemi kurgulamak gerekli olabilmektedir.

Identity Server 4

Temel Özellikler
Identity Server 4, Asp .Net Core 2 için geliştirilmiş olan bir OpenID Connect ve OAuth 2.0 kütüphanesidir. Temel özelliklerini aşağıdaki gibi sıralayabiliriz.

  • Tüm uygulamalar(web, mobil, servis) ve iş akışları için merkezi yetki kontrol mantığı sağlar.
  • Farklı uygulama tipleriniz için SSO(Single Sign-on) desteği sunar.
  • Çeşitli istemci türleri için API’lara erişim izni verir, örneğin sunucudan sunucuya, web uygulamalarına, SPA’lara ve mobil uygulamalara erişim sağlar.
  • Azure Active Directory, Google, Facebook gibi harici kimlik sağlayıcıları için destek sağlar.
  • IdentityServer’ın bir çok özelliği ihtiyaçlarınıza uyacak şekilde özelleştirilebilir.
  • IdentityServer, üstünde ticari ürünler oluşturmaya izin veren Apache 2 lisansını kullanır.

OpenId ve OAuth 2.0
OpenId kimlik doğrulama ağı dahilindeki web sitelerine üye olmaksızın login imkanı tanıyan bir sistemdir. Böylelikle bir web sitesine üye olmak için gereksiz vakit kaybı önlenmiş olunur. En büyük dezavantajı ise şifreniz çalındığında diğer tüm web siteleri için de tehlikeli bir durum oluşur. OpenId edinebilmek için OpenId servisi sunan bazı web siteleri mevcuttur. Örneğin yahoo bunlarda biridir. Bir OpenId hesabı edinmek için yahoo’nun şuradaki web adresini kullanabilirsiniz.

OAuth 2.0 uygulamalar arası veri erişimine imkan tanıyan bir yetkilendirme protokolüdür. Örneğin mevcut projenizde yetkilendirmeyi farklı bir web sitesi(Facebook, Twitter, Google) üzerinden yapmak isteyebilirsiniz ki bu OAuth protokolünün kullanıldığı anlamına gelir.

Örnek Uygulama
Basit bir örnek uygulama ile Identity Server konusunu anlamaya çalışacağız. İstemcilerin bir sunucuya istekte(request) bulunup token alacağı ve sonrasında bu token ile Claims bilgilerini çekeceğimiz bir çalışma hazırlayacağız.

İlk olarak Asp Net Core Web Application oluşturalım ve template olarak Web Application seçelim. Sonrasında authentication olarak Individual User Accounts seçelim.

Identity Server 1

Bu aşamada seçtiğimiz template dahilinde bir proje hazırlanmış olacak ve şu aşamada Identity Server için gerekli olan nuget paketlerini indirmemiz gerekecek. 2 pakete ihtiyacımız olacak ve bunları aşağıdaki gibi listeleyebiliriz.

Projenin port ayarını 5000 olarak güncelleyelim. Proje ayaklandığında http://localhost:5000 şeklinde URL adresi görmeliyiz. Port güncellemesinin ardından istemci bilgilerini tanımlayabileceğimiz bir sınıfa ihtiyacımız olacak ki bu istemcilerin sunucuya nasıl bir request ile geleceklerini belirleyecek. Bunun için github ortamındaki şu örnek config dosyasını olduğu gibi kullanabiliriz. Config sınıfını inceleyecek olursak içinde Client listesini ve ApiResource tanımlamalarının yapıldığını görürüz.

Şimdi Config sınıfı içindeki bazı noktalara değinelim:

  • ApiSecrets: Endpoint gözlemcisi olarak kullanılır. API, bu hazırlanan name ve secret ile kimlik doğrulaması yapabilir.
  • Scopes: Varsayılan olarak bir istemcinin herhangi bir kaynağa erişimi bulunmaz. Scope tanımlaması ile lgili kapsam adlarını ekleyerek izin verilen kaynak listesi belirtmiş oluruz.
  • AllowedGrantTypes: Grant type, bir istemcinin bir IdentityServer ile etkileşimde bulunmak istediğini belirtmenin bir yoludur. Farklı tipleri vardır ve bunları şuradan inceleyebilirsiniz.

Config sınıfı içindeki Client listesi ve ApiResource tanımlamalarını DI(Dependency Injection) servisi içine dahil etmeliyiz. Bu yapılandırmayı aşağıdaki gibi hazırlayabiliriz.

            services.AddIdentityServer()
                    .AddDeveloperSigningCredential()
                    .AddInMemoryPersistedGrants()
                    .AddInMemoryApiResources(Config.GetApiResources())
                    .AddInMemoryClients(Config.GetClients())
                    .AddAspNetIdentity<ApplicationUser>();

Şimdi pipeline için Identity Server tanımlamamızı aşağıdaki gibi belirtelim.

app.UseIdentityServer();

İstemcilerin token ihtiyacını karşılayacak olan server projesini oluşturduğumuza göre şimdi kullanıcıya ait claim bilgilerini döndüren bir Api uygulaması hazırlayacağız. Burada temel olarak yapacağımız şey istemcinin gönderdiği token bilgisine göre ilgili kullanıcı bilgisini json formatta döndürmek olacaktır. ConfigureServices ve Configure tanımlamalarını aşağıdaki gibi belirtelim.

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvcCore()
                .AddAuthorization()
                .AddJsonFormatters();

            services.AddAuthentication("Bearer")
                .AddIdentityServerAuthentication(options =>
                {
                    options.Authority = "http://localhost:5000";
                    options.RequireHttpsMetadata = false;
                    options.ApiName = "api1";
                });
        }
        
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseAuthentication();
            app.UseMvc();
        }

Şimdi istemciye claim bilgilerini döndüreceğimiz bir action hazırlayalım.

    [Route("[controller]")]
    [Authorize]
    public class IdentityController : ControllerBase
    {
        [HttpGet]
        public IActionResult Get()
        {
            return new JsonResult(User.Claims.Select(item => new { item.Type, item.Value }));
        }
    }

Şimdi Identity Server ile iletişimi sağlayacak olan istemci uygulamamızı yazacağız. Bunun için bir Console uygulaması hazırlamak işimizi görecektir. Öncelikle 5000 portu üzerinde çalışan server projesi üzerinden token elde edeceğiz ve sonrasında bu elde ettiğimiz token ile Api tarafından User bilgisine ulaşacağız.

        private static async Task MainAsync()
        {
            // Endpoint için metadata erişimi
            var disco = await DiscoveryClient.GetAsync("http://localhost:5000");

            // Token talebi
            var tokenClient = new TokenClient(disco.TokenEndpoint, "client", "secret");
            var tokenResponse = await tokenClient.RequestClientCredentialsAsync("api1");

            if (tokenResponse.IsError)
            {
                Console.WriteLine(tokenResponse.Error);
                Console.ReadLine();
            }

            Console.WriteLine(tokenResponse.Json);
            Console.WriteLine("\n\n");

            // API ile iletişim
            var client = new HttpClient();
            client.SetBearerToken(tokenResponse.AccessToken);

            var response = await client.GetAsync("http://localhost:5001/identity");
            if (!response.IsSuccessStatusCode)
            {
                Console.WriteLine(response.StatusCode);
            }
            else
            {
                var content = await response.Content.ReadAsStringAsync();
                Console.WriteLine(JArray.Parse(content));
            }
            Console.ReadLine();
        }

Tüm projeleri run ettiğimizde sonucu aşağıdaki gibi görebiliriz. İlk etapta elde ettiğimiz token bilgisini ve buna ait expire süresini görmekteyiz. Sonrasında bu token bilgisini kullanarak Api tarafından detaylı User bilgisine erişim sağladık. Buradaki erişim sağladığımız çeşitli claim tiplerini detaylı araştırmak isterseniz şuradaki adresi kullanabilirsiniz.

Identity Server 1

Sonuç
Sonuç olarak Identity Server 4 oldukça gelişmiş bir kimlik yönetim kütüphanesidir diyebiliriz. Farklı örnek uygulamaları incelemek isterseniz şuradaki github ortamına göz atabilirsiniz. Bunun yanında Identity Server’ın resmi web sitesine şuradaki adresten girip detaylı materyallere erişebilirsiniz.

Hepinize mutlu kodlamalar dilerim.

Tarih:ASP .NET CoreWeb Security

3 Yorum

  1. Turgut Turgut

    Yardımlarınız için Teşekkürler Beyfendi İyi Çalışmalar Dilerim.

  2. buse buse

    Merhaba, config dosyasının llinkinin güncellenmesi gerekiyor.
    Teşekkürler,
    İyi çalışmalar

  3. Nihan Nihan

    config dosyası uçmuş.

Bir cevap yazın

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.