OpenIdConnect ve OAuth2 Nedir?
Merhaba, bu yazıda geliştirdiğimiz uygulamalarımızın güvenliğinde kullandığımız OpenId Connect ve OAuth2 protokollerini açıklamaya çalıştım. Bu protokolleri .Net Core uygulamalarımız içerisinde kullanabileceğimiz bir açık kaynak kodlu bir framework olan IdentityServer4’ü bir sonraki yazımda paylaşmaya çalışacağım. IdentityServer4 ile Client Credential yazım için tıklayın.
OAuth2 Nedir?
OAuth2 uygulamalar arası veri iletişiminde kullanılan açık bir yetkilendirme protokolüdür. OAuth2 desteği içeren, geliştirdiğimiz bir uygulama ile yetkilendirdiğimiz kullanıcı grubu, OAuth2 protokolü ile başka bir uygulamanın veri kaynağına erişim izni verebiliriz. Örneğin,bir kullanıcının, geliştirdiğiniz web uygulamasına facebook, google veya github ile bağlanması veya giriş yapması gibi. OAuth2, kullanıcı doğrulama için (authentication) değil, yetkilendirme (authorization) için kullanılan bir protokoldür. Google, Facebook, twitter gibi uygulamalar OAuth2 desteği vermektedirler ve bu uygulamalarda doğrulanmış kullanıcılar, Oauth2 protokolünü kullanan ve bu uygulamalara güvenen diğer geliştirilmiş web uygulamalarına yetkilendirilebilirler.
Kısaca OAuth2, uygulamalar arası yetkilendirme (Authorization) işlemini yürütür.
OAuth2 Yetki Tipleri – Akışları
Bir client uygulaması ile token servisi arasındaki etkileşimin nasıl olacağını OAuth2 yetki tipleri ( Grant Types) veya yetki akışları belirler. OAuth2 protokolünün kullanıcı kimliğini doğrulama işlemi sağlamayan ama bunun için gerekli desteği bulunduran bir protokol olduğunu söylemiştik.
OAuth2 yetki tipleri:
- Authorization Code Grant
- Implicit Grant
- Resource Owner Password Credential Grant
- Client Credential Grant
OAuth2 akışlarında bulunan roller;
Resource Owner : Sistemde bulunan veriye sahip kişi(son kullanıcı) veya uygulamadır.
Client Application: Bir client uygulaması, kaynak sahibi(Resource Owner) adına korumalı veri kaynaklarına erişen bir uygulamadır. (Web, Javascript, mobile…)
Client uygulamalar public ve confidential (gizli) şekilde sınıflandırılmıştır. Public client uygulamalar; native applications ( masa üstü, tablet, mobil vb. Cihazlar için geliştirilmiş uygulamalar), user-agent based applications ( Javascript tabanlı veya SPA uygulamalar ).
Cofidential (gizli) client uygulamalar; web uygulamalar veya geleneksel web uygulamalardır.
Resource Server: korunması gereken veri kaynağını yöneterek access token ‘a göre ve yetki kapsamına göre erişime izin verir. Korunan veri kaynağı, örneğin kişinin profil bilgisi veya kişisel bilgileri olabilir.
Authorization Server: Kimliği doğrulanmış client uygulamalar için resource owner yetkisi dahilinde access token verir. Kısaca yetki ve erişimi yönetir.
Not:
OpenId connect ile bu yapıya eklenti olarak kimlik doğrulama (authentication) akışları eklenmiştir.
- Implicit Grant
- Resource Owner Password Credential Grant
- Client Credential Grant
AUTHORIZATION CODE GRANT (OAuth2)
Bu yetki tipi confidential(gizli) veya public(genel) client uygulamalar için authorization code ile bir access token elde etmek veya değiştirmek için kullanılır. Access token elde eden kullanıcı kaynaklara bu token ile erişebilir. Mobil ve Web uygulamalar için uygundur.
Eğer Authorization Code akışını mobil uygulamada veya client secret saklayamadığımız bir uygulamada kullanmak istersek, authorization code saldırılara karşı korumak için PKCE(Proof Key for Code Exchange) uzantısını kullanmalıyız.
NOT: Client secret bilgisi saldırganların asıl hedefidir. Mobil ve SPA (Single Page App) uygulamalarında PKCE kullanarak client secret bilgisi olmadan yetki akışını sağlarız. PKCE ile dinamik client secret üretip access code değiştirilir.
Kısaca akış adımları;
- Uygulama (client) bir tarayıcı ile kullanıcıyı AuthServer ‘a gönderir.
- Kullanıcı yetki istemi ve uygulamanın isteğini onaylar.
- Kullanıcı, query string içersinde authorization code ile tekrar uygulamaya yönlendirilir.
- Uygulama access token için authorization code değiştirir. Bunu AuthServer’ın token end point’ini kullanarak yapar.
Kod değiştirme adımı saldırganın access token erişmesini engeller. Çünkü access token, uygulama ile AuthServer arasında güvenli bir kanaldan iletilir.
IMPLICIT GRANT(OAuth2)
Authorization Code Grant ‘a benzer adımlara sahiptir. Bu yetki tipinde authorization code yetki tipinden farkı, kullanıcı kimlik doğrulamasından sonra authorization code yerine access token, client uygulamaya doğrudan verilir. Client secret bilgisi yerine client id bilgisi sorgulanarak access token elde edilir. Refresh token bu yetki tipi için kullanılmaz.
Bu yetki tipi daha çok public client( Spa, javascript) türü uygulamalar için uygundur. Client secret bilgisinin bulunmaması ve authorization code yetki tipine göre daha kolay access token elde edildiği için daha çok javascript uygulamalarda kullanılmıştır.
Implicit Grant native mobile uygulamalarda kullanılması öneriliriken, günümüzde authorization code, PKCE eklentisi ile kullanımı önerilmektedir.
RESOURCE OWNER PASSWORD CREDENTIAL GRANT (OAuth2)
Implicit yetki tipine benzer şekilde AuthorizationServer bir kez istekte bulunarak acess token elde etmeye yarar. Burada kullanıcı(Resource Owner) ,kullanıcı adı şifre bilgileri ile client uygulama üzerinden gönderir diğer yetki tipleri gibi AuthorizationServer üzerinde bir login sayfasına yönlendirilmez. Client uygulama, aldığı kullanıcı adı ve şifre bilgileri ile AuthorizationServer üzerinde doğrulama işlemini yapar ve Auth.Server client uygulamaya access token bilgisi ve opsiyonel olarak refresh token döner.
Genelde kendi login mekanizması olan client uygulamalarda kullanılması önerilmektedir. Bu yetki mekanizması Resource Owner(kullanıcı) ile client uygulama arasında çok güvenilir bir ortamın olduğu durumlarda tercih edilmelidir.
CLIENT CREDENTIAL GRANT (OAuth2)
Client Credential yetkilendirme mekanizması son kullanıcının kimliğini doğrulamaz. Sadece client uygulamanın doğrulanması işlemini yapar. Resource Owner Password Credential benzer ama bir login yapısı veya etkileşimi bulunmaz. Client uygulaması, ClientId ve Client secret ileAuthorizationServer da doğrulanıp, client uygulamayı temsil eden bir access token elde edilir.
Client Credentital yetki yapısı genelde son kullanıcı doğrulaması gerekmeyen machine to machine uygulamalarda kullanılabilir.
OpenId Connect Nedir ?
OpenId 1.0, OAuth2 protokolü üzerine kurulmuş basit bir kimliklendirme katmanıdır. Client uygulamaların için bir Authorization Server tarafından son kullanıcı kimlik doğrulaması yapmasının yanı sıra REST benzeri bir yapı ile son kullanıcının basit profil bilgilerini elde etmesini sağlar. OpenId Connect (OIDC) önceki versiyonlarına göre API dostu bir yapı sağlar.OIDC, OAuth2 Authorization Code Grant yapısını genişleten bir eklentidir.
OIDC, işlemleri basit tutar, OAuth2 üzerine kurulmuştur ve token (JWT) kullanımını kolaylaştırır. OIDC web uygulamalar, mobil uygulamalar, Single page uygulamalar (SPA) ve sunucu taraflı uygulamalar ile entegre olabilir.
OIDC Kullanılan Terimler
Relying Party (RP) : Bu SAML2 den gelen bir terimdir. Bir OpenId sağlayıcısından son kullanıcı doğrulaması bekleyen bir OAuth2 client uygulamasını ifade eder. OpenId sağlayıcısı OAuth2 client uygulamasına kimlik doğrulama sonucunu güvenli bir şekilde döndürür. Böylece Client uygulama Relying Party (güvenen taraf) olarak adlandırılır.
OpenId Provider (OP) : Client uygulamaya(Rely Party) için son kullanıcı kimlik doğrulaması(Authentication) yapan, son kullanıcı ve authentication hakkında claim sağlayan OAuth2 Yetkilendirme (Authorization) suncusudur.
End-User : OAuth2 de geçen bir terim. Kimlik doğrulaması yapılmış kişi veya uygulama.
User Agent : OAuth2 de mevcut olan bir terimdir. HTTPS isteklerini başlatan, Client ugyulama ve OpenId Provider tarafından oluşturulan yönlendirmeleri işleyen bir yapı. ( Browser)
Resource Server: Access Token kullanarak korunan kaynağa gelen istekleri kabul eden ve yanıtlayabilen korunan veri kaynaklarını barındıran sunucudur.
OIDC OAuth2 protokolüne ne gibi authentication özellikleri kazandırmıştır ?
- Claim stnadartları ( ID Token claim standartları)
- Kullanıcı bilgilerini içeren ID Token ‘ın dijital olarak imzalamış veya isteğe bağlı olarak şifrelenmiş şekilde kullanılması zorunlu kılar.
- Önceden giriş yapmış olsa bile son kullanıcının kimlik doğrulamasını zorunlu kılar.
- Client uygulamalar için ek claim bilgileri sağlayabilme
- Son kullanıcının nasıl kimlik doğrulama yapacağını belirler.
- Access Token koruma seviyesi sağlar. Bu işlemi client bazında tanımlayabiliriz.
- Ayrık ve toplu claim desteği sağlar.
OIDC Kullanılan EndPointler
Authorization Endpoint : OAuth2 de tanımlanmış bir endpoint’tir. Son kullanıcıdan kimlik doğrulama ve onay alma (consent) işleminden sorumludur.
Token Endpoint : Bir client uygulamanın authorization code veya client Id ve client secret ile access token ile değişimini sağlar.
UserInfo Endpoint : OIDC ile tanımlanmış bir endpoint’tir. Bir client veya resource server ek claim taleplerinin sağlandığı noktadır.
OIDC Authentication Akışları
OAuth2 Authorization Grant (Yetkilendirme) ve Extension Grant’ların (uzanti yetkilendirmelerin) tanımlarken OIDC, authentication ( kimlik doğrulama) akışları tanımlar. Üç kimlik doğrulama (authentication) akışı bulunmaktadır. Bu akışlar, OpenId Provider (OP) ‘a iletilen parametreler, cevapların içeriği ve nasıl işlendiğine göre farklılık gösterir. Authorization Endpoint’e yapılan isteklerin arasındaki fark response_type parametresi ile belirlenir. Akışlar ve parametre değerleri ;
Authorization Code Flow -> “code”
Implicit Flow -> “id_token” veya “id_token token”
Hybrit Flow -> “ code id_token” veya “code token” veya “code id_token token”
Bu akış ve response_type değerleri ifade edilmek istenen örneğin; response_type parametresinde code değeri gördüğümüzde authorization endpoint her zaman bize authorization code döndürür. id_token bir response_type dahil edilirse yanıtta id_token bulunur veya token response_type parametresine dahil edilirse auhorization endpoint’den gelen cevaba bir access token dahil edilecektir. Kısaca bu parametre, cevap yapısını ve bağlı olan (client) uygulamanın hangi işlem adımlarını kullanacağını belirler. Bu üç akış için Authorization Code Flow, OAuth2 Authorization Code Grant‘in genişletilmiş halidir. OIDC Implicit Flow ve Hybrid Flow ise Authorization Code Flow ‘un genişletilmiş halidir.
Authorization Code Flow (OIDC)
OAuth2 Authorization Code Grant’ın OpenId Connect versiyonudur veya karşılığıdır. Bu akışın yanıt tipi (response_type) code olarak tanımlanmıştır.OAuth2 Authorization Code Grant yapısında bulunan tüm adımları içerir.
Kimlik doğrulama isteği ile client uygulama (Relying Party), User Agent’i (Browser) Open Id sağlayıcısına(OP) yönlendirir. Yani son kullanıcı, OpenId sağlayıcı tarafında bulunan login olabileceği sayfaya yönlendirilir. Böylece client uygulama, kullanıcı kimlik doğrulama bilgilerini görmez. OpenId Connect kimlik doğrulama (authentication) protokolü olarak adlandırılsa bile, kullanıcının kimlik doğrulamasının nasıl yapılacağı detayı ile ilgilenmez. Bu OpenId sağlayıcısının içerisinde uygulamaya bağlı olarak tanımlanmaktadır. Hatta client uygulama için ayrıca izin mekanizması (Consent) içerebilir.
Kullanıcı doğrulama (Login) başarılı ise OpenId sağlayıcı kullanıcıyı authorization endpoint’ yönlendirir. Authorization endpoint, authorization code içeren bir http yönlendirme ile client uygulamaya (RP) yönlendirir. Eğer kimlik doğrulama hatalı ise authorization end point hata bilgisi içeren bir yönlendirme yapar. Böylece client uygulama (RP), kullanıcı şifresini görmeden authorization code bilgisini elde eder. Şimdi client uygulama (RP) token endpoint’den access token, Id Token ve diğer bilgileri alması gerekmektedir. Bunun için RP, token endpoint’e authorization code, clientid ve client uygulamanın güvenilir olup olmamasına bağlı olarak client secret parametrelerini göndererek token’lara erişir. Elde edilen access token, ID Token’da bulunan at_hash (Authorization Hash) parametresi kullanılarak doğrulanır. Bu opsiyoneldir ama token doğrulanması önerilmektedir. Son olarak elde edilen access token ile userinfo endpoint ve resource server (api) ‘a erişebiliriz.
Implicit Flow (OIDC)
OAuth2 Implicit Grant benzemektedir, fakat OIDC Authorization Code Flow yapısının genişletilmiş halidir. Authorization Endpoint’den User Agent’a(Browser) authentication response bir parçası olarak ID Token ve Access Token döner. Client Secret bilgisini barındıramayacağımız public client uygulamalarda kullanılır.
Bu akış için Authorization Endpoint id_token ve id_token token şeklinde iki adet response_type parametre değerine sahip olabilir.
Akışın response_type olarak id_token token döndüğü durumda ;
Authorization Code Flow da olduğu gibi kullanıcı,User Agent (Browser) kullanarak client uygulamaya ulaşır. Client uygulama, Authorization Endpoint üzerinden OpenId sağlayıcısına gönderdiği bir Http isteği ile Login sayfası veya akışına ulaşır. Kullanıcı kimlik doğrulaması başarılı ise Authorization Endpoint üzerinden User Agent’a (Browser) bir Http cevabı döner. Authorization Code Flow ‘dan farkı dönen cevabın IDToken ve Access Token bilgisini içermesidir.User Agent (Browser), Token bilgilerini yönlendirme URL’i içerisinden ayrıştırması, ID token bilgisini çıkarıp isteği client uygulamaya iletmesi gerekmektedir. Client uygulama yönlendirilen isteğin içerisinden token ve diğer bilgileri çıkarır ve Authentication cevabını doğrular.Eğer Client uygulama ekstra claim’lere ihtiyacı olursa, OpenId sağlayıcının UserInfo Endpoint’i kullanarak bu bilgilere erişebilir. Daha sonra Client uygulama, access token bilgisini Authorization Header’a ekleyerek Resource Server ( Web Api) ‘da bulunan kaynağa veya veriye erişebilir.
Resource Server, kendisine gelen ve access token içeren isteğin içerisinden access token ayrıştırıp token doğrulaması yapar. Eğer Resource Server son kullanıcı ile ilgili claim bilgilerine erişmek isterse access token ile OpenId sağlayıcısının UserInfo Endpoint’ine istekte bulunup bu bilgilere erişebilir.
Akışın response_type değeri id_token ise aynı adımlar geçerlidir. Yalnız bu durumda bir Resource Server (Web Api) bulunmaz. Burada sadece client uygulama (RP) kimlik doğrulaması OpenId sağlayıcı tarafından gerçekleştirilir.
Sonuç olarak Implicit Flow, client uygulama doğrulamasına ihtiyaç duymadığı için Single Page uygulamalar ve native mobil uygulamalar için uygundur. Ayrıca bu akış için Refresh Token bulunmaz.
Hybrid Flow (OIDC)
Bu akış, diğer iki akışın birleştirilmiş halidir. Bundan dolayı akışın farklarını belirteceğim. Diğer iki akış detaylarını içeren bir yapısı bulunmaktadır. Bu akışı kullanan client uygulamalar client secret bilgisini barındırabilen uygulamalar (Server Side) olmalıdır . Ayrıca bu akışla refresh token kullanarak uzun süreli yaşayabilen token ve oturum yapısı kullanılabilir.
Authorization Code Flow’da (basic flow) da client id ve client secret bilgisine ihtiyaç duyarak ön kanal (front channel) ‘dan client doğrulaması yapılır. Daha sonra Token Endpoint’den access token elde edilir ve arka kanal (back channel) kullanılarak client uygulamaya ulaştırılır.
Implicit Flow’da gerekli token’lar Authorization Endpoint’de üretilir ve client doğrulaması için client secret bilgisine ihtiyaç yoktur. Bu işlemler ön kanal üzerinden (front channel) gerçekleştirilir.
Hybrid Flow iki kanalı kullanarak işlemleri gerçekleştirmektedir. Bu akışta code, id_token ve token response_type değerlerinin bu akış için tanımlanmış üç adet kobinasyonlarını kullanabiliriz. Bunlar;
- response_type = code token
- response_type = code id_token
- response_type = code id_token token
Sonuç;
Yetki tiplerini ve akışları geliştirdiğimiz sisteme, kullanıcı yapılarına göre tercih etmeliyiz. Gelişen teknoloji ve insan faktöründen dolayı bu yetki ve akış mekanizmalarının güncel hallerini kullanmamız uygulama ve verilerimizin güvenliği için önemlidir.