OpenIddict #4 – OpenId Connect
Merhaba,
Bu içeriğimizde OpenIddict kütüphanesi ile OpenID Connect protokolünü nasıl kullanabileceğimizi ve ekstra kullanıcı bilgilerini sorgulamanın nasıl yapılabileceğini inceliyor olacağız.
Her şeyden önce temel terminolojiyi oturtabilmek için OpenId Connect’in ne olduğunu izah ederek başlamakta fayda görüyorum.
OpenID Connect Nedir?
Esasında OpenID Connect hakkında detaylı bilgiyi OAuth 2.0 ve OpenID Connect Protokolleri Nelerdir? başlıklı makalemden edinebilirsiniz. Amma velakin burada da ufak bir tanımlamada bulunmanın bu içeriğin insicamı için gerekli olduğunu düşündüğümden ilgili yazıdan ufak bir alıntıyla devam etmek istiyorum…
…OpenID Connect, esasında bir protokolden ziyade OAuth 2.0 üzerinde kimlik doğrulama(authentication) işlemlerini üstlenen bir katmandır. API dostu bir yapı sağlamakta ve işlemleri basit tutarak JWT kullanımını kolaylaştırmaktadır…
OpenID Connect protokolü kimlik doğrulama işlemlerini üstlendiği için içerisinde kullanıcı bilgilerini barındıran identity token adında bir token sağlamaktadır. Bizler bu token’ı kullanarak ekstradan kullanıcı bilgilerini edinebilmekte ve varsa ekstradan işlemleri gerçekleştirebilmekteyiz.
OpenID Connect Protokolünü Etkinleştirme
OpenIddict, OpenID Connect protokolünü zaten uygulamaktadır ve openid
scope’u eşliğinde yapılan taleplere karşılık identity token döndürmektedir. Bunu aşağıdaki gibi test edebilir ve identity token‘ın elde edildiğini görebilirsiniz.Yukarıdaki istek neticesinde response olarak access token eşliğinde aşağıdaki gibi bir identity token elde edilecektir.
Bu identity token değerini jwt.io üzerinden çözümleyerek incelersek eğer;
şeklinde bir içeriğe sahip olduğunu gözlemlemekteyiz.
Identity token’a istediğiniz bilgileri depolayabilirsiniz. Bunun için eğer ki akış olarak authorization code flow’u kullanıyorsanız ‘AuthorizationController’ içerisindeki ‘Authorize’ metodunda yahut client credential flow’u kullanıyorsanız da token endpoint’ine karşılık gelen ‘Exchange’ fonksiyonunda çalışabilirsiniz.
public async Task<IActionResult> Authorize(string accept, string deny) { . . . var identity = new ClaimsIdentity(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme); identity.AddClaim(OpenIddictConstants.Claims.Subject, result.Principal.Identity.Name, Destinations.AccessToken); identity.AddClaim(JwtRegisteredClaimNames.Aud, "Example-OpenIddict", Destinations.AccessToken, Destinations.IdentityToken); identity.AddClaim("ornek-claim", "ornek claim value", Destinations.AccessToken, Destinations.IdentityToken); identity.AddClaim("a", "a value", Destinations.AccessToken, Destinations.IdentityToken); identity.AddClaim("b", "b value", Destinations.AccessToken, Destinations.IdentityToken); . . . }
Userinfo Endpoint’i
OpenID Connect protokolü kullanıcı hakkında bilgi alınabilmesi için bir endpoint sağlayabilmektedir. Bunun için endpoint’e dair aşağıdaki gibi konfigürasyonun gerçekleştirilmesi gerekmektedir.
.AddServer(options => { options.SetTokenEndpointUris("/connect/token") .SetAuthorizationEndpointUris("/connect/authorize") .SetLogoutEndpointUris("/connect/logout") //Kullanıcı bilgilerini edinebilmek için userinfo endpoint'ini set ediyoruz. .SetUserinfoEndpointUris("/connect/userinfo"); options.UseAspNetCore() .EnableTokenEndpointPassthrough() .EnableAuthorizationEndpointPassthrough() .EnableLogoutEndpointPassthrough() .EnableUserinfoEndpointPassthrough(); . . . });
Bu konfigürasyondan sonra authorization server’ı yeniden ayağa kaldırıp
https://localhost:7047/.well-known/openid-configuration
adresine istek gönderirseniz userinfo endpoint’inin uygulamaya eklendiğini görebilirsiniz.Bu adımdan sonra customer’lar ile hangi kullanıcı bilgilerini paylaşmak istiyorsak ona göre userinfo endpoint’ini geliştirmeye odaklanabiliriz. Bunun için ‘AuthorizationController’ içerisinde ‘Userinfo’ action’ınını aşağıdaki gibi geliştirebiliriz.
public class AuthorizationController : Controller { . . . [Authorize(AuthenticationSchemes = OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)] [HttpGet("~/connect/userinfo")] public async Task<IActionResult> Userinfo() { var claimPrincipal = (await HttpContext.AuthenticateAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme)).Principal; return Ok(new { Name = claimPrincipal.GetClaim(OpenIddictConstants.Claims.Subject), Aud = claimPrincipal.GetClaim(OpenIddictConstants.Claims.Audience), A = claimPrincipal.GetClaim("a"), B = claimPrincipal.GetClaim("b"), OrnekClaim = claimPrincipal.GetClaim("ornek-claim"), }); } }
Dikkat ederseniz userinfo endpoint’ine geçerli bir access token olduğu taktirde erişilebilmektedir. Gerekli token eşliğinde /connect/userinfo
adresine GET isteği yapılırsa aşağıdaki gibi kullanıcı bilgileri elde edilecektir.
İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…
Not : Örnek uygulamanın kaynak kodlarına aşağıdaki github adresinden erişebilirsiniz.
https://github.com/gncyyldz/OpenIddict-Authorization-Server-Example