Keycloak Server ile API’larınıza JWT Validasyonu Nasıl Ekleyebilirsiniz? – Bölüm 2
  1. Anasayfa
  2. ASP.Net

Keycloak Server ile API’larınıza JWT Validasyonu Nasıl Ekleyebilirsiniz? – Bölüm 2

2

İlk bölümde Keycloak kurulum ve konfigurasyonundan kısaca bahsetmiştim. Bu bölümde de .NET 6 minimal API tarafında neler yapmak gerektiğinden bahsedeceğim. Aslında standart bir token validasyonundan farklı bir kodlama gerekmiyor, bu nedenle farklı bir authenticaton sunucusu da kullanıyorsanız benzer şekilde bu kodlardan da faydalanabilirsiniz.

İlk olarak dotnet new web -o mshowtominapi komutu ile yeni bir web api oluşturup, dotnet new gitignore komutu ile gitignore dosyasını ekledikten sonra Visual Studio Code ile açıyorum (Resim-1). Asıl konumuz olmadığı için .NET 6 Minimal API detaylarına girmeyeceğim.

Resim-1

Kodlamaya geçmeden önce ihtiyacım olan Microsoft.AspNetCore.Authentication.JwtBearer nuget paketinin bu yazıyı yazarken güncel olan 6.0.1 versiyonunu Resim-2‘de göreceğiniz şekilde csproj dosyasına ekliyorum.

Resim-2

Kod tarafında konfigurasyondan okumamız gereken 2 değer var: Issuer ve Key. Issuer token’ı kimden aldığımız bilgisi, Key bilgisini ise gelen token’ı gerçekten Issuer tarafından verilip verilmediğini anlamak için kullanacağım public key. Buradaki asıl amaç ise bu doğrulama işlemi için tekrar tekrar Keycloak’a gitmemek.

Bu key bilgisini de https://mshowto-keycloak.azurewebsites.net/auth/realms/mshowto adresinden (sondaki mshowto kullandığım realm ismi) ya da Keycloak Administration Console’da Realm Settings/Keys altından bulabilirsiniz (Resim-3).

Resim-3

Services’a token işlemlerinde standart olarak kullandığımız AddAuthentication ve AddJwtBearer methodlarını burada da kullanıyorum. Token validasyonu için gerekli parametreleri de aşağıda göreceğiniz şekilde set ediyorum. İlk bölümde belirttiğim gibi Audience eklemediğim için ValidateAudience=false olarak set ettim. Get methoduna RequireAuthorization ekleyerek artık bu methodu JWT doğrulaması yapmadan çağıramayacağımı da belirtmiş oluyorum.

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

var builder = WebApplication.CreateBuilder(args);
var issuer = builder.Configuration["Jwt:Issuer"];

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>
{
    opt.RequireHttpsMetadata = true;
    opt.Authority = issuer;
    opt.TokenValidationParameters = new()
    {
        ValidateIssuer = true,
        ValidateAudience = false,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = issuer,
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
    };
});

builder.Services.AddAuthorization();

var app = builder.Build();


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

app.MapGet("/", () => "Hello World!").RequireAuthorization();

app.Run();

Issuer ve Key bilgilerini appsettings.json’a ekleyebilirsiniz, ama ben daha güvenli bir yol olarak ASP.NET Core Secrets Manager kullanarak saklamayı tercih edeceğim. Böylece kodunuzu source control’e eklediğinizde bu bilgileri de exclude etmeyi unuttum demeden rahatlıkla commit/check-in işlemini yapabilirsiniz.

İlk olarak Resim-4‘te de göreceğiniz gibi, proje klasörü içerisinde dotnet user-secrets init komutu ile secret store’u aktifleştireceğim. Bu komut ile csproj dosyasına UserSecretsId adında bir guid eklendiğini görebilirsiniz. Sonrasında da dotnet user-secrets set komutu ile de secret store’a kaydedeceğim key ve value bilgilerini giriyorum. Son olarak da dotnet run ile projeyi çalıştırıyorum.

Resim-4

Uygulamamız hazır, şimdi sırada Keycloak’tan access token alarak Postman üzerinden ilgili GET isteğini gönderme işlemi var. Bunun için her request öncesinde access token almak için ilk bölümde bahsettiğim şekilde bir “Get Token” isteği yapıp, response içerisindeki token değerini kopyalayıp API’a auth header olarak gönderebilir, ya da bu işi API’a her istekte otomatik yapmak için Postman’in nimetlerinden faydalanabiliriz. İlk olarak Postman’de yeni bir environment (dev) oluşturup buraya Resim-5‘te göreceğiniz şekilde değişkenleri tanımlıyorum. Pre-request script sekmesinde de istek öncesince gidip access token değerini alacak bir JS kodu ekliyorum. GET isteğini gönderdiğimde ise Hello World! cevabını başarıyla aldığımı görebiliyorum.

Resim-5

Script’in detayına baktığımızda ise aslında JS ile grant type, client id ve client credentials verileri ile bir POST isteği yapıp, response içerisinden access_token değerini okuyup bunu Postman değişkenine atıyorum.

const getTokenRequest = {
  method: "POST",
  url: pm.environment.get("authserver"),
  header: 'Content-Type: application/x-www-form-urlencoded',
  body: {
      mode: 'urlencoded',
      urlencoded: [
          { key: "grant_type", value:  pm.environment.get("grant_type") },
          { key: "client_id", value:  pm.environment.get("client_id") },
          { key: "client_secret", value: pm.environment.get("client_secret") }
      ]
  }
};

pm.sendRequest(getTokenRequest, (err, response) => {
  const jsonResponse = response.json();
  const newAccessToken = jsonResponse.access_token;

  pm.variables.set("access_token", newAccessToken);
});

NOT: GET isteği için Authorization bilgisini değişken üzerinden okuması için Resim-7‘deki gibi bir düzenleme de yapmanız gerekiyor.

Resim-7

Bu konuyla ilgili sorularınızı  alt kısımda bulunan yorumlar alanını kullanarak sorabilirsiniz.

Referanslar

www.mshowto.org

Keycloak – Getting started

Safe storage of app secrets in development in ASP.NET Core | Microsoft Docs

Writing pre-request scripts | Postman Learning Center

TAGs: Azure, Yazılım Geliştiriciler için Azure, Keycloak, JWT, Authentication, Postman, Web API, REST, SAML, OpenID, OAuth, VS Code, ASP.NET Core, NET 6, Minimal API

Bu İçeriğe Tepkin Ne Oldu?
  • 12
    harika_
    Harika!!
  • 0
    be_enmedim
    Beğenmedim
  • 0
    _ok_iyi
    Çok iyi
  • 0
    sevdim_
    Sevdim!
  • 0
    bilemedim_
    Bilemedim!
  • 0
    olmad_
    Olmadı!
  • 1
    k_zd_m_
    Kızdım!

Mert Yeter, lisans eğitimini Yıldız Teknik Üniversitesi'nde, yüksek lisans eğitimini ise Bahçeşehir Üniversitesi'nde tamamlamıştır. Yazılım dünyasına üniversitenin ilk yıllarında aldığı QBasic ile başlayan Mert, .NET ve SQL Server gibi Microsoft teknolojileri ile devam etmiş; yüksek lisans tezini ise Linux konusunda yapmıştır. Netaş ve Ziraat Teknoloji gibi sektörün önde gelen firmalarında C#, .NET, SQL Server, Cisco Contact Center ürünleri ve Linux üzerine çalışmış, bir çok firmaya da bu konularda danışmanlık vermiştir.

Yazarın Profili
İlginizi Çekebilir

Bültenimize Katılın

Tıklayın, üyemiz olun ve yeni güncellemelerden haberdar olan ilk kişi siz olun.

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

Yorumlar (2)

  1. 26/02/2023

    Selamlar, yukarıdaki adımları uyguluyor olmama rağmen hala 401 hatası alıyorum sorun neyden kaynaklanıyor olabilir ?

    • Merhaba, ValidateIssuer=false olarak deneyebilir misiniz? Eğer bu şekilde çalışıyorsa Issuer adresini kontrol edebilirsiniz.

Bir yanıt yazın

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