APISIX Üzerinde Keycloak ile SSO Oluşturma
Bu blog yazısında, Apache APISIX üzerinde Keycloak ile Single Sign-On (SSO) nasıl oluşturulacağını anlatacağım. Apisix’in openid-connect eklentisini kullanarak Keycloak ile entegre olacak ve kullanıcıların tek bir kimlik doğrulama işlemi ile birden fazla servise erişim sağlamasını gerçekleştireceğiz.
Ek olarak, Keycloak tarafında token imza doğrulamasını çevrimdışı (offline) olarak nasıl yapabileceğimizi ve APISIX üzerinde istemci (client) bazlı servis erişimi kısıtlamasını nasıl yapabileceğimizi de anlatacağım.
Apache APISIX
APISIX, açık kaynak kodlu, yüksek performanslı bir API Gateway ve mikro servis yöneticisidir. Yüksek esneklik, genişletilebilirlik ve kullanım kolaylığı sunar. APISIX, Lua tabanlı bir mimariye sahiptir ve NGINX’in üstünde çalışır.
Keycloak
Keycloak, açık kaynak kodlu bir kimlik ve erişim yönetim sistemidir. Kullanıcı kimlik doğrulama, yetkilendirme, SSO, sosyal giriş ve daha fazlasını destekler. Keycloak, OAuth 2.0, OpenID Connect ve SAML 2.0 gibi standartları kullanır.
Keycloak ile APISIX arasında SSO (Single Sign-On) oluşturma
Authorization Code Grant Type ile SSO
Authorization Code Grant Type, kullanıcıların kimlik doğrulama işlemi için kullanıcı adı / password bilgisini asla uygulamaya vermeden, doğrudan Keycloak üzerinden login olmasını sağlar ve kullanıcıyı uygulamaya redirect eder.
APISIX üzerinde bu grant type’ı kullanarak Keycloak ile SSO oluşturmak için aşağıdaki yapılandırmayı kullanabiliriz:
"openid-connect": {
"bearer_only": true,
"client_id": "'"$OIDC_CLIENT_ID"'",
"client_secret": "'"$OIDC_CLIENT_SECRET"'",
"discovery": "'"$OIDC_DISCOVERY"'",
"scope": "openid profile",
"redirect_uri": "http://localhost:9080/anything/callback"
}
Client Credentials Grant & Password Grant Type ile SSO
Client Credentials Grant Type, istemcinin (client) kimlik doğrulama işlemi için kendi kimlik bilgilerini kullanarak erişim token’ı elde etmesini sağlar. Password Grant Type ise kullanıcı adı ve şifre kullanarak erişim token’ı elde edilmesini sağlar. APISIX üzerinde bu grant type’ları kullanarak Keycloak ile SSO oluşturmak için aşağıdaki yapılandırmaları kullanabiliriz:
"openid-connect": {
"use_jwks": true,
"client_id": "'"$OIDC_CLIENT_ID"'",
"client_secret": "'"$OIDC_CLIENT_SECRET"'",
"discovery": "'"$OIDC_DISCOVERY"'",
"scope": "openid profile",
"redirect_uri": "http://localhost:9080/anything/callback"
}
NOT: Client Credentials Grant Type’ı kullanabilmek için Keycloak tarafında
Service Accounts Enabledözelliğinin aktif olması gerekmektedir. Password Grant Type’ı kullanabilmek için iseDirect Access Grants Enabledözelliğinin aktif olması gerekmektedir.
NOT: Yukarıdaki örneklerde
bearer_onlyözelliği Authorization Code Grant Type içintrue, diğer iki grant type için isefalseolarak ayarlanmıştır. Bu ayar, APISIX’in kullanıcı yönlendirmesi yapıp yapmayacağını belirler.
use_jwksparametresitrueolarak ayarlandığında, APISIX token imzalarını doğrulamak için Keycloak’ın JWKS endpoint’ini kullanır. Bu endpoint, Keycloak tarafından otomatik olarak oluşturulan ve public key’leri içeren bir URL’dir. APISIX, bu endpoint’e istek göndererek public key’leri alır ve token imzalarını doğrular.
Peki token imzalarını çevrimdışı olarak nasıl doğrularız?
Bunun için use_jwks parametresini false olarak ayarlayıp, public_key parametresini kullanabiliriz. public_key parametresi, Keycloak tarafından oluşturulan public key’in PEM formatındaki temsilini içerir.
"openid-connect": {
"use_jwks": false,
"public_key": "-----BEGIN PUBLIC KEY-----/n***/n-----END PUBLIC KEY-----"
}
Bu bize çevrimdışı token imza doğrulama imkanı sağlar ve performansı artırır.
Keycloak tarafında public key’i almak için aşağıdaki adımları takip edebiliriz
- Keycloak yönetici konsoluna gidin.
Realm Settingssekmesine gidin.Keyssekmesine gidin.Public Keyalanında,RS256algoritması için oluşturulan public key’i bulun.
Dilerseniz Keycloak’ın varsayılan public key’ini kullanmak yerine, kendi özel anahtar çiftinizi de kullanabilirsiniz. Bunun için Keycloak’ta yeni bir key pair oluşturup, private key’i kullanarak token’ları imzalayabilir ve public key’i APISIX’te kullanabilirsiniz.
- Keycloak yönetici konsoluna gidin.
Realm Settingssekmesine gidin.Keyssekmesine gidin.Providerssekmesine gidin.Add providerbutonuna tıklayın veRSAseçeneğini seçin.- Name:
my-rsa-key - Priotity:
0 - Enabled:
ON - Active:
ON - Private RSA Key: Kendi private key’inizi buraya yapıştırın.
- X509 Certificate: İsteğe bağlı olarak sertifikanızı buraya yapıştırabilirsiniz.
- Algorithm:
RS256
- Name:
Savebutonuna tıklayın.
Bu adımları takip ettikten sonra, Keycloak tarafından oluşturulan yeni key pair’i kullanarak token’ları imzalayabilir ve APISIX’te public key’i kullanarak token imzalarını doğrulayabilirsiniz.
Client Bazlı Servis Erişiminin JWT audience Claim ile Kısıtlanması
APISIX üzerinde SSO ile kullanıcının tüm güvenlikli servislere erişimini gerçekleştirdik.
Peki ben servislerime farklı istemcilerin erişimini nasıl kısıtlarım?
Evet, yukarıdaki örneklerde client_id ve client_secret kullanarak APISIX’in Keycloak ile SSO yapmasını sağladık. Ancak bazen belirli bir servise erişimi istemci bazlı olarak kısıtlamak isteyebiliriz. Bu durumda audience claim’ini kullanabiliriz.
Client Bazlı Servis Erişiminin JWT audience Claim ile Kısıtlanması
APISIX üzerinde bu adımları takip ederek istemci bazlı servis erişimi kısıtlamasını yapabiliriz
"openid-connect": {
"claim_validator": {
"issuer": {
"valid_issuers": [
"http(s)://<domain>:<port>/auth/realms/your-realm"
]
},
"audience": {
"match_with_client_id": true,
"required": true
}
},
}
Keycloak tarafında ise ilgili istemci için audience mapper’ını oluşturup, Included Client Audience değerini ilgili istemcinin client_id değeri ile aynı yapmamız gerekmektedir.
Aşağıdaki adımları takip ederek Keycloak tarafında audience mapper’ını oluşturabiliriz
- Keycloak yönetici konsoluna gidin.
Clientssekmesine gidin ve ilgili istemciyi seçin.Client Scopessekmesine gidin.- İlgili scope’a tıklayın ve ardından
Add mapperbutonuna tıklayın. Configure a new mapperseçeneğini seçin.- Audience mapper’ını aşağıdaki gibi ayarlayın:
- Name:
audience - Mapper Type:
Audience - Included Client Audience: İlgili istemcinin
client_iddeğeri - Add to ID token:
ON - Add to access token:
ON - Add to userinfo:
OFF
- Name: