← Back to Posts

OpenID Connect (OIDC) ile Kimlik Doğrulama - Nasıl Yapılır?

OIDC Nedir?

OAuth 2.0 spesifikasyonlarını uygulayan ve REST/JSON istek akışlarını kullanarak kimlik sağlayıcılarını uygulamalara entegre etmeyi kolaylaştıran kimlik doğrulama protokolüdür. Başka bir deyişle, bir yetkilendirme sunucusu tarafından gerçekleştirilen kimlik doğrulamasına dayalı olarak istemcilerin, son kullanıcının kimliğini doğrulamasına ve temel profil bilgilerini ve mevcut oturum bilgilerini elde etmesine imkan sağlar. Böylece sistemin kimlik ve erişim yönetimini üçüncü parti bir servise delege etmiş olursunuz.

OIDC, OpenID ve OpenID Connect aynı anlamları taşır. Farklı farklı yerlerde bu isimlendirmelerinin türevlerini görebilirsiniz.

OAuth Nedir?

İlk bölümde bahsettiğim gibi OIDC, OAuth üzerine kurulu bir protokol olduğu için çalışma prensibi olarak bir çok ortak yapıya sahipler. Bu sebeple basitçe OAuth’dan bahsetmekte fayda olacağı kanısındayım.

OAuth, aralarında hiçbir bağ olmayan sunucu ve servislerin birbirlerine kimlik bilgilerinden haberdar olmadan izin verilen kaynaklara/verilere nasıl güvenli bir şekilde kimlik doğrulamalı olarak erişim izni verilebileceğini tanımlayan açık standartlı yetkilendirme protokolüdür. OAuth’un kullanım senaryoları düşünüldüğünde hepsinin ortak noktası birbirleri ile alakası olmayan iki farklı servisin veya uygulamanın birlikte çalışarak kullanıcı veya uygulama için bir sonuç elde etmesidir. Örneğin, bulut depolama alanındaki fotoğraflarınızı tarihlerine göre albümleyen bir uygulamayı kullanmak istiyorsunuz. Bu durumda albüm uygulaması bulut deponuzdaki fotoğraflara erişmek isteyecektir. Her iki uygulamaya da erişim sağlamak için kimlik bilgisine ihtiyaç duyduğu için OAuth’un olmadığı bir senaryoda albüm uygulamasına bulut deponuzun kimlik bilgilerini tanıtmanız beklenir fakat OAuth kullanılarak kimlik bilgilerinizi paylaşmadan sadece bulut depolama uygulaması üzerinde kimliğinizi doğrulayarak albüm uygulamasına yetki verebilmek mümkün hale geldi. Böylece albüm uygulaması ile sadece fotoğraflarınızı paylaşmış olmakla beraber şifrenizi ve diğer verilerinizi korumuş oldunuz. Bu özellik Facebook, Google gibi kullanıcı profil bilgilerini depolayan servislere uyarlanarak yetkilendirmenin yanında kimlik doğrulama işlemleri içinde kullanılmıştır.

OIDC vs OAuth

Bu noktada yukarıda verilen OAuth örneğinde hali hazırda bir kimlik doğrulaması gerçekleştirildiği halde neden hala kimlik doğrulamak için OIDC’ye ihtiyaç duyulduğu sorusu sorulabilir. Buna açıklık getirmek için OIDC ile OAuth arasındaki farkları anlamak gerekiyor.

OAuth, makinelerin makineler üzerinde kullanıcının onayladığı yetki kapsamındaki kaynağa erişim sağlaması için dizayn edilmiş, geliştirilmiştir. OpenID ise için kullanıcıların makineler üzerinde erişim sağlayabilmesi için geliştirilmiştir. OAuth’un kullanıcı erişimleri için kullanılmasındaki en büyük sorun tasarım amacından ötürü güvenliktir. Nat Sakimura blog yazısında OAuth ile kimlik doğrulamasını ‘sudo’ kimlik doğrulaması olarak tanımlamıştır. Sudo terimiyle anlatılmak istenilen oturum açma işleminin, makinenin oturum açma işlemini taklit etmesi için gerekli anahtarlarının paylaşılması amacıyla yapıldığını belirtmektir. Aksi halde OAuth gerçek bir kimlik doğrulama için gerekli kullanıcı kimliği, profil bilgisi, veya herhangi bir öznitelik bilgisini sağlamaz. Bu bağlamda OIDC’nin getirdiği yeniliklerden en önemlisi kullanıcı kimliğinin doğrulanıp erişim için gerekli anahtarın paylaşılmasının yanı sıra doğrulama yöntemlerini ve güvenilirliğini içeren anahtarın (id_token) sağlanması ve erişim kapsamının sağlayıcı (bkz. google) tarafından önceden hazırlanmış kullanıcı bilgilerinin sorgulanması için oluşturulan kaynaklar (/user_info) ile sınırlandırılmasıdır. Böylece kimlik doğrulama işlemi basitleştirilmiş, standardize edilmiş ve daha güvenli hale getirilmiştir.

Nasıl Çalışır?

Nasıl çalışır kısmını daha iyi şekillendirmek için ben bir OIDC protokolü üzerinden kimlikleme ve yetkilendirme işlemlerini yapan ve bu anlamda kapsamlı özellikler sunan bir ürün olan MonoSign üzerinden örneklerimi vereceğim. Sizlerde dilerseniz MonoSign'ı buradan deneyerek bu örnekleri kendiniz de yapabilirsiniz.

Uygulamamızın kimlik doğrulama görevini OIDC ile MonoSign’a delege ettiği bir senaryo düşündüğümüz durumda en az 3 aktöre ihtiyaç duyarız.

Kullanıcı: Uygulamaya giriş yapmaya çalışan birey.

Uygulama: Henüz yetkisi olmadığı bir kaynağa erişim sağlamaya çalışan bireyin kimliğini doğrulamak isteyen istemci.

Kimlik Sunucusu: Uygulamaya giriş yapacak kullanıcının kimlik bilgilerine sahip olan ve bu bilgilerin doğrulanması işini gerçekleştirip profil bilgilerini paylaşacak kaynak.

İhtiyaca ve platforma göre kimlik doğrulama işlemleri farklılık göstersede en temel akışlardan biri aşağıdaki gibidir.

alt_text

Yukarıdaki akışı daha iyi anlayabilmek için OIDC mesajlaşmaları sırasında gönderilen istekleri inceleyelim ve parametreleri açıklayalım.

Uygulamamız, kendisine yetkisiz bir erişim isteği geldiği durumda tarayıcıyı kimlik doğrulama işlemleri için belirttiğimiz kimlik sunucusuna OAuth isteği ile yönlendiriyor. Bu aşamada kullanıcı, aktif bir oturumunun olup olmadığı kontrolünün sağlanması suretiyle MonoSign’ın oturum açma formuna yönlendirilecek ve kimlik bilgilerinin girilmesi istenilecek.

Örnek kimlik doğrulaması yönlendirmesi:

HTTP/1.1 302 Found
Location: https://monosign.com/login?
          response_type=code
          &scope=openid
          &client_id=s6BhdRkqt3
          &state=af0ifjsldkj
          &redirect_uri=https%3A%2F%2Fuygulama.com%2Fcb

Scope: OAuth üzerinde yetkilendirmenin seviyesini belirtir. Bu parametre ile OpenID isteği olduğunu belirtiyoruz.

Client ID: Kimlik sunucusu tarafındaki konfigürasyonlar sırasında uygulamamız için atanan kimlik.

State: Uygulamamız tarafından oluşturulan nadir anahtar. Genellikle CSRF saldırılarını önlemek amacıyla gönderilen state’in gelen state ile eşleşip eşleşmediği kontrolü yapılır.

Redirect URI: Kimlik doğrulama sonrasında uygulamamızın kullanıcıyı yönlendirmek istediği adres.

MonoSign tarafından kullanıcı kimliği doğrulandıktan sonra uygulama tarafından gönderilen istek içerisinde şifrelenmiş olarak bulunan redirect_uri adresine auth_code ile yönlendirilir.

Örnek başarılı kimlik doğrulaması yönlendirmesi:

HTTP/1.1 302 Found
Location: https://uygulama.com/cb?
          code=SplxlOBeZQQYbYS6WxSbIA
          &state=af0ifjsldkj

Code: id_token ile değiştirilmek üzere gönderilen auth_code

Kullanıcının kimliğini başarılı bir şekilde doğrulamış olduk fakat profil bilgilerine hala sahip değiliz. Opsiyonel olarak kimlik sunucusundan access_token talep ederek kullanıcının profil bilgilerine erişim sağlayabiliriz.

Örnek yetkilendirme yönlendirmesi:

POST /token HTTP/1.1
Host: monosign.com
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

grant_type=authorization_code
 &code=SplxlOBeZQQYbYS6WxSbIA
 &redirect_uri=https%3A%2F%2Fuygulama.com%2Fcb

Grant Type: id_token ile değiştirilecek anahtarın tipini belirtir

Örnek yetkilendirme cevabı:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache

{
  "id_token": "eyJhbGciOiJ..."
  "access_token": "SlAV32hkKG",
  "token_type": "Bearer",
  "expires_in": 3600,
}

ID Token: Oturum ve kullanıcı bilgilerini içeren ve uygulamanın kimlik sunucusuna kaydedilirken belirlediği method ile doğrulaması gereken şifrelenmiş kod.

Access Token: Kimlik sunucunun OpenID kapsamında sunduğu arayüzlere (/user_info vb.) ulaşması için gerekli kod.

Gerekli tokenlere sahip olduktan sonra artık kullanıcının izin verilen bilgilerine erişim sağlanabilir.

Örnek kullanıcı profilini talep etme isteği:

GET /userinfo HTTP/1.1
Host: monosign.com
Authorization: Bearer sa7Aebo6Ookoo0oh

Örnek başarılı kullanıcı profili talep etme cevabı:

HTTP/1.1 200 OK
Content-Type: application/json

{
  "sub"            : "alice",
  "email"          : "[email protected]",
  "email_verified" : true,
  "name"           : "Alice Adams",
  "picture"        : "https://c2id.com/users/alice.jpg"
}

Uygulama: MonoSign Kullanarak Kimlik Doğrulamasını Delege Etmek

Bu örnek projemizde ASP.Net Core uygulamamızı MonoSign’a kayıt ederek kimlik doğrulama adımlarını MonoSign’a yönlendireceğiz.

Öncelikle, aşağıdaki komut ile .net core mvc uygulamamızı oluşturuyoruz.

dotnet new mvc MonoSignOIDC

OpenID Connect paketini projemize eklemek için MonoSignOIDC.csproj dosyasına referansını ekliyoruz

<ItemGroup>
   <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.9" />
 </ItemGroup>

Sonraki aşamaya geçmeden önce uygulamamızı MonoSign’a kaydedip gerekli kimlik bilgilerini alacağız. Bunun için MonoSign üzerinde uygulamalar bölümünden yeni bir uygulama oluşturmamız gerekiyor.

alt_text

Uygulama detayına girerek anahtarlar bölümünden OpenID Connect anahtarı oluşturuyoruz.

alt_text

Anahtar atamasının tamamlanmasının ardından artık kimlik bilgilerimizi kullanarak MonoSign’ı uygulamamıza entegre edebiliriz.

alt_text

Oluşturmuş olduğumuz projemizin Startup.cs dosyasına eklemiş olduğumuz OpenID Connect paketiyle ilgili ayarları ekliyoruz.

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();
    services.AddAuthentication(options =>
    {
        options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
    })
    .AddCookie()
    .AddOpenIdConnect(o =>
    {
        o.ClientId = "980d6430-373a-476c-bd11-8d7b3be35415";
        o.ClientSecret = "423e9ab4-08ed-48fc-815a0e-35a0e654ae9d";
        o.Authority = "https://sso-demo.monosign.com";
        o.ResponseType = OpenIdConnectResponseType.Code;
    });
    services.AddControllersWithViews();
}

Standart yetkilendirme metodlarını kullanabilmemiz için gerekli ara katmanları ekliyoruz.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

Uygulamamızı basit tutmak adına MVC şablonu ile beraber gelen /privacy sayfasını doğrulanmış kullanıcılar için sınırlayalım. Bunun için [Authorize] niteliğini ilgili Controller'ün ilgili Action'ına ekliyoruz.

[Authorize]
public IActionResult Privacy()
{
   return View();
}

Entegrasyon işlemini tamamlamakla beraber bundan sonra localhost/Home/Privacy adresine bulunulan isteklerde kullanıcıların kimlik doğrulama sayfasına yönlendirilmelerini bekliyoruz.

Bitirirken

Genel olarak OIDC üzerinde Kimlik Doğrulama işlemlerinin nasıl yapılacağı üzerinde durduk. Kimlik ve ERişim Yönetimi konusunda OIDC ile birlikte, OAuth, JWT, SAML, WS-Federation gibi oturum/yetki protokollerini destekleyen MonoSign'a göz atabilirsiniz.

Modern protokolleri kullanarak oturum açma işlemlerinizi kolaylaştırmak mı istiyorsunuz?

Bize Ulaşın!

Faydalı Olabilecek Bağlantılar