Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

IdentityServer4 Yazı Serisi #14 – Merkezi Üyelik Sistemi – Refresh Token İle Yeni Access Token Alma

Merhaba,

IdentityServer4 Yazı Serisinin bir önceki Merkezi Üyelik Sistemi – Access Token İle API’lerle Haberleşme başlıklı makalemizde IdentityServer’dan elde edilen access token ile API’lara nasıl istek yapıldığını ele almıştık. Bu içeriğimizde ise client tarafında authentication property’ler arasında elde edilen refresh token’ı kullanarak nasıl yeni bir access token ve id token’ın alınabileceğini ve bunların mevcut authentication propertyler ile nasıl değiştirilebileceğini inceleyeceğiz.

Bizler refresh token örneklendirmesini, bu ondördüncü makaleye kadar hasbel kader geliştirdiğimiz IdentityServer4Example uygulaması üzerinden irdeleyeceğiz. Geliştirdiğimiz uygulamanın son versiyonu zaten mevcudiyette refresh token üretimi için tüm alt yapıyı sağladığından dolayı direkt olarak refresh token ile access token talebini ele alacak ve bu işlemin mantığını daha net kavrayabilmek için, Postman ve client uygulaması olmak üzere iki farklı istemcide ayrı ayrı örneklendireceğiz.

Postman’de Refresh Token İle Yeni Token Alma

İlk olarak client uygulamasında bir refresh token elde edelim.
IdentityServer4 Yazı Serisi #14 – Merkezi Üyelik Sistemi – Refresh Token İle Yeni Access Token Alma
Ardından bu refresh token değerini kullanarak Postman uygulaması üzerinden aşağıdaki konfigürasyonlar eşliğinde yeni bir access token talebinde bulunalım.

client_id Client id değeri.
client_secret Client secret değeri.
grant_type İstek türü. Hangi istek yapılacaksa ona uygun tür bildirilmelidir. Bizler refresh token talebinde bulunacağımızdan dolayı ‘refresh_token’ değerini vereceğiz. Diğer taleplere nazaran alabileceği değerleri orjinal kaynağından ‘grant_type’ başlığı altında inceleyebilirsiniz.
username Kullanıcı adı.
password Kullanıcı şifresi.
refresh_token Refresh token değeri. Yeni bir access token değeri talep edebilmek için mevcudiyetteki refresh token değerinin verilmesi gerekmektedir.

IdentityServer4 Yazı Serisi #14 – Merkezi Üyelik Sistemi – Refresh Token İle Yeni Access Token Alma

Yukarıdaki ekran görüntüsünde görüldüğü üzere her talep neticesinde yeni bir access token ve refresh token üretilmektedir. Her talepte access token’ından ziyade refresh token’ın yeniden üretilme sebebi ise Auth Server’da ilgili client’ı tanımlayan nesnede ‘RefreshTokenUsage’ özelliğine ‘OneTimeOnly’ değerinin verilmesidir. Eğer ki ‘ReUse’ değeri verilseydi her talep neticesinde aynı refresh token değeri kullanılabilecekti.
IdentityServer4 Yazı Serisi #14 – Merkezi Üyelik Sistemi – Refresh Token İle Yeni Access Token Alma

Client Uygulamasında Refresh Token İle Yeni Token Alma

Esas itibarıyla refresh token ile client uygulaması üzerinden access token talebinde bulunulması gerekecektir. Bu duruma istinaden aşağıdaki örneği irdelemekte fayda vardır.

    public class AuthController : Controller
    {
        public async Task<IActionResult> NewAccessToken()
        {
            string refreshToken = await HttpContext.GetTokenAsync(OpenIdConnectParameterNames.RefreshToken);
            HttpClient httpClient = new HttpClient();
            RefreshTokenRequest refreshTokenRequest = new RefreshTokenRequest()
            {
                ClientId = "OnlineBankamatik",
                ClientSecret = "onlinebankamatik",
                RefreshToken = refreshToken,
                Address = (await httpClient.GetDiscoveryDocumentAsync("https://localhost:1000")).TokenEndpoint
            };
            TokenResponse tokenResponse = await httpClient.RequestRefreshTokenAsync(refreshTokenRequest);
            AuthenticationProperties properties = (await HttpContext.AuthenticateAsync()).Properties;

            properties.StoreTokens(
                new List<AuthenticationToken> {
                  new AuthenticationToken
                                         {
                                             Name = OpenIdConnectParameterNames.IdToken,
                                             Value = tokenResponse.IdentityToken
                                         },
                  new AuthenticationToken
                                         {
                                             Name = OpenIdConnectParameterNames.AccessToken,
                                             Value = tokenResponse.AccessToken
                                         },
                  new AuthenticationToken
                                         {
                                             Name = OpenIdConnectParameterNames.RefreshToken,
                                             Value = tokenResponse.RefreshToken
                                         },
                  new AuthenticationToken
                                         {
                                             Name = OpenIdConnectParameterNames.ExpiresIn,
                                             Value = DateTime.UtcNow.AddSeconds(tokenResponse.ExpiresIn).ToString("O")
                                         },
                                       });
            await HttpContext.SignInAsync("OnlineBankamatikCookie", (await HttpContext.AuthenticateAsync()).Principal, properties);
            return RedirectToAction(nameof(BankamatikController.Index));
        }
        public async Task<IActionResult> Index()
        {
            AuthenticateResult authenticateResult = await HttpContext.AuthenticateAsync();
            IOrderedEnumerable<KeyValuePair<string, string>> properties = authenticateResult.Properties.Items.OrderBy(p => p.Key);
            return View(properties);
        }
    }

Yukarıdaki kod bloğunun 5 ile 14. satırları arasında refresh token ile yeni bir access token talebinde bulunulması, 15 ile 41. satırları arasında ise elde edilen authentication property’ler ile mevcudiyette bulunanların değiştirilmesi ele alınmıştır. Tek tek bu kodları izah etmemiz gerekirse eğer;

  • 5. satır
    Authentication property’ler içerisinden refresh token değeri elde edilmiştir.
  • 7 – 13. satır
    Refresh token ile request yapabilmemiz için ilgili client’ın bilgilerini tutan nesne oluşturulmuştur. Burada dikkat ederseniz kullanıcının username ve password bilgileri girilmemektedir. Bunun nedeni, ilgili dataların cookie’de tutuluyor ve talep neticesinde IdentityServer4’e gönderiliyor olmasıdır.
  • 14. satır
    ‘RefreshTokenRequest’ nesnesini kullanarak IdentityServer4 sunucusuna ‘grant_type’ değeri ‘refresh_token’ olan bir istek gönderir ve neticede ‘TokenResponse’ olarak yeni access token, id token ve refresh token değerlerini elde eder.
  • 15. satır
    Mevcudiyetteki tüm authentication property’ler elde edilir.
  • 17 – 39. satır
    Mevcudiyette elde edilen authentication property’ler ile talep neticesinde üretilen yeni değerleri ‘StoreTokens’ fonksiyonu ile değiştirmekteyiz.
  • 40. satır
    İlgili kullanıcı yeni authentication property’ler ile güncellenmekte ve bunun için tekrar ilgili değerler eşliğinde SignIn yaptırılmaktadır.
  • 43 – 47. satır
    Authentication property’leri çekip, listeleyen bir action tasarlanmıştır.

IdentityServer4 Yazı Serisi #14 – Merkezi Üyelik Sistemi – Refresh Token İle Yeni Access Token Alma
Görüldüğü üzere refresh token ile yeni bir access token talep edilmekte ve elde edilen tüm değerler öncekileriyle değiştirilmektedir.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Not : Örnek uygulamayı indirebilmek için buraya tıklayınız.

Bunlar da hoşunuza gidebilir...

3 Cevaplar

  1. Sinan dedi ki:

    Türkçe içerikli en iyi yazılım bloğu. İçerikler harika. Özellikle yazı serileri çok iyi. Emeğinize sağlık. Teşekkürler.

  2. Enes dedi ki:

    Elinize sağlık hocam gayet güzel çoğu yazınızı takip diyorum. Pekiştirmek için ideal yazılardan bir tanesi…

Bir cevap yazın

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