1.6.2. OIDC
Geliştiriciler için OIDC Entegrasyonu Rehberi#
Bu belge, Keysis'te OIDC entegrasyonunun nasıl çalıştığına dair geliştiricilere rehberlik etmeyi amaçlamaktadır.
Ayarlamalar:
- Uygulama çalıştırıldığında /.well-known/openid-configuration dosyası oluşturulur.
- application-authentication.yml dosyasında:
- AUTH_OIDC_LOGIN_PAGE_URL -> UI URL ile aynı olmalı.
- keycloak docker-compose.yml dosyasında:
- extra_host ile local auth instance erişilebilir olmalı.
- Veritabanında:
- Bir client tanımı yapılmalıdır.
- redirect_uris eşleşmesinde realms ve display name alanları uyumlu olmalı.
Bilgiler:
- OIDC
OpenId Connect ile Keysis login akışı kullanılarak uygulamalarınızı authenticate yapabilmek için kullanılan özelliktir. Keycloak uygulaması ayarlamalar bölümündeki detaylar göz önüne alınarak çalıştırıldıktan sonra aşağıdaki adımlar takib edilerek OIDC akışı test edileblir.
- Veritabanında yazılı redirect_urls ile uyumlu olacak şekilde bir realms tanımı yapılır.
- Identity Provider bölümünden OIDC v1.0 seçilir
- Use discovery endpoint ile "/.well-known/openid-configuration" servis ucu deploy ettiğiniz url olarak eklendiğinde tüm OIDC tanımlamaları otomatik gelecektir.
- well-known ucunu provide eden url ile keycloakda yapılan extra_host tanımı uymalıdır. Aksi taktirde keycloak docker localde çalışan well-known ucunu provide eden instance içerisine istek atamaz.
- Sertifika ayarlamaları ile uğraşmamak için test aşamasında "Validate Signatures" kısmını false olarak bırakmalısınız.
- Client-Id alanına => auth-experimental
- Client-Secret alanına => test
- Bu aşamadan sonra keycloak üzerinde client sekmesine gelerek Home URL yazan uçlardan birine tıklayarak signin yapmalısınız.
- OIDC için tanımladığınız display name ile login ol seçeneğini seçerek keysis arayüzlerinden login olduktan sonra geri keycloak ekranına yönlendirileceksiniz.
Örnek Docker Compose Dosyası
version: '3'
volumes:
postgres_data:
driver: local
services:
keycloak:
container_name: keycloak
image: quay.io/keycloak/keycloak:latest
network_mode: hvl_core_network
command: ["start-dev"]
restart: unless-stopped
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://hvlpostgresmultipledatabases:5432/hvl
KC_DB_USERNAME: HVL
KC_DB_PASSWORD: hvl12345
KC_HEALTH_ENABLED: 'true'
KC_HTTP_ENABLED: 'true'
KC_METRICS_ENABLED: 'true'
# KC_HOSTNAME: keycloak.hvlnet.net:8080
# KC_HOSTNAME_PORT: 8180
# KC_HOSTNAME_URL: keycloak.hvlnet.net:8080
KC_PROXY: reencrypt
KEYCLOAK_ADMIN: admin
KEYCLOAK_ADMIN_PASSWORD: password
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: Pa55w0rd
ports:
- "8080:8080"
extra_hosts:
- "keycloak.hvlnet.net:YOUR_IP_ADDRESS"
- "keysis.hvlnet.net:127.0.0.1"
OIDC Kullanıcısı Oluşturma#
OIDC kullanıcıları için aşşağıdaki örnek tablo oluşuturulmuştur.
<changeSet author="may (generated)" id="271020230822-2" context="dev">
<createTable tableName="kys_oidc_client">
<column name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="kys_oidc_client_pkey"/>
</column>
<column name="created_by" type="VARCHAR(50)">
<constraints nullable="false"/>
</column>
<column name="created_at" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="false"/>
</column>
<column name="updated_at" type="TIMESTAMP WITHOUT TIME ZONE">
<constraints nullable="false"/>
</column>
<column name="updated_by" type="VARCHAR(50)">
<constraints nullable="false"/>
</column>
<column name="uuid" type="VARCHAR(36)">
<constraints nullable="false"/>
</column>
<column name="obj_version" type="INTEGER"/>
<column name="client_authentication_methods" type="VARCHAR(1000)">
<constraints nullable="false"/>
</column>
<column name="authorization_grant_types" type="VARCHAR(1000)">
<constraints nullable="false"/>
</column>
<column name="client_id" type="VARCHAR(100)">
<constraints nullable="false"/>
</column>
<column name="client_id_issued_at" type="TIMESTAMP WITHOUT TIME ZONE">
</column>
<column name="client_name" type="VARCHAR(200)">
<constraints nullable="false"/>
</column>
<column name="client_secret" type="VARCHAR(200)">
</column>
<column name="client_secret_expires_at" type="TIMESTAMP WITHOUT TIME ZONE">
</column>
<column name="client_settings" type="VARCHAR(2000)">
<constraints nullable="false"/>
</column>
<column name="post_logout_redirect_uris" type="VARCHAR(1000)">
</column>
<column name="redirect_uris" type="VARCHAR(1000)">
</column>
<column name="scopes" type="VARCHAR(1000)">
<constraints nullable="false"/>
</column>
<column name="token_settings" type="VARCHAR(1000)">
<constraints nullable="false"/>
</column>
</createTable>
<createTable tableName="kys_oidc_client_aud">
<column name="id" type="BIGINT">
<constraints nullable="false" primaryKey="true" primaryKeyName="kys_oidc_client_aud_pkey"/>
</column>
<column name="rev" type="INTEGER">
<constraints nullable="false" primaryKey="true" primaryKeyName="kys_oidc_client_aud_pkey"/>
</column>
<column name="revtype" type="SMALLINT"/>
<column name="deleted" type="SMALLINT"/>
<column name="client_authentication_methods" type="VARCHAR(1000)"/>
<column name="authorization_grant_types" type="VARCHAR(1000)"/>
<column name="client_id" type="VARCHAR(255)"/>
<column name="client_id_issued_at" type="TIMESTAMP WITHOUT TIME ZONE"/>
<column name="client_name" type="VARCHAR(255)"/>
<column name="client_secret" type="VARCHAR(255)"/>
<column name="client_settings" type="VARCHAR(2000)"/>
<column name="post_logouts_redirect_uris" type="VARCHAR(1000)"/>
<column name="redirect_uris" type="VARCHAR(1000)"/>
<column name="scopes" type="VARCHAR(1000)"/>
<column name="token_settings" type="VARCHAR(1000)"/>
</createTable>
</changeSet>
Tabloda yer alan kolonları açıklamaları aşağıdaki gibidir:
- id (BIGINT): OIDC istemcisine ait her kaydın ID'sidir. Bu sütun primary key olarak kullanılır.
- created_by (VARCHAR(50)): OIDC istemci kaydını oluşturan kullanıcı ya da işlemdir. Bu alan zorunludur.
- created_at (TIMESTAMP WITHOUT TIME ZONE): OIDC istemci kaydının oluşturulma zamanını temsil eden zamandır. Bu alan zorunludur.
- updated_at (TIMESTAMP WITHOUT TIME ZONE)OIDC istemci kaydının son güncellenme zamanıdır. Bu alan zorunludur.
- updated_by (VARCHAR(50)) OIDC istemci kaydını son güncelleyen kullanıcı ya da işlemdir. Bu alan zorunludur.
- uuid (VARCHAR(36))OIDC istemcisine ait unique identifier. Null olamaz.
- obj_version (INTEGER): Optimistic lock kontrolü için kullanılan bir sürüm numarasıdır.
- client_authentication_methods (VARCHAR(1000)): OIDC istemcisinin kimlik doğrulama için kullanacağı yöntemler (örneğin, istemci gizli anahtarı, sertifikalar vb.). Bu alan zorunludur ve birden fazla yöntem içerebilir.
- authorization_grant_types (VARCHAR(1000)): İstemciye tanımlanan yetkilendirme izin türlerini belirtir (örneğin, authorization_code, client_credentials, password). Bu alan zorunludur.
- client_id (VARCHAR(100)): OIDC istemcisi için benzersiz bir tanımlayıcıdır. Bu alan zorunludur.
- client_id_issued_at (TIMESTAMP WITHOUT TIME ZONE): İstemci ID'sinin verildiği zamanı temsil eden zamandır.
- client_name (VARCHAR(200)): OIDC istemcisinin adı, genellikle istemci ID’si ile ilişkilendirilen uygulama ya da hizmeti temsil eder. Bu alan zorunludur.
- client_secret (VARCHAR(200)): OIDC istemcisinin kimlik doğrulamak için kullandığı paroladır.
- client_secret_expires_at (TIMESTAMP WITHOUT TIME ZONE): İstemci parolasının geçerliliğinin sona erdiği zaman damgasıdır.
- client_settings (VARCHAR(2000)): İstemciye ait ek ayarları içeren JSON ya da başka bir formatta veridir. Bu alan zorunludur.
- post_logout_redirect_uris (VARCHAR(1000)): İstemcinin çıkış yaptıktan sonra yönlendirileceği URI’lerin listesidir. İsteğe bağlı bir alandır.
- redirect_uris (VARCHAR(1000)): İstemcinin izin verilen yönlendirme URI’lerinin listesidir. Başarılı bir kimlik doğrulama sonrasında yetkilendirme sunucusunun yanıtı göndereceği URL'lerdir.
- scopes (VARCHAR(1000)): İstemcinin talep ettiği kapsamların listesidir. Kapsamlar, istemcinin talep ettiği erişim seviyelerini belirtir (örneğin, openid, profile, email). Bu alan zorunludur.
- token_settings (VARCHAR(1000)): İstemciye verilen token’lar ile ilgili ayarlardır. Örneğin, geçerlilik süreleri, izin verilen token türleri vb. Bu alan zorunludur.
<addDefaultValue tableName="kys_oidc_client" columnName="id" defaultValueSequenceNext="kys_oidc_client_seq"/>
OIDC Kullanıcısı Ekleme#
<changeSet author="may (generated)" context="dev" id="755887855996-1">
<validCheckSum>8:29060716d5aa8f455393a76e1ac1e1b3</validCheckSum>
<insert tableName="kys_oidc_client">
<column name="id" valueSequenceNext="KYS_OIDC_CLIENT_SEQ"/>
<column name="created_by" value="unknown"/>
<column name="created_at" valueDate="CURRENT_TIMESTAMP"/>
<column name="updated_at" valueDate="CURRENT_TIMESTAMP"/>
<column name="updated_by" value="unknown"/>
<column name="uuid" value="AUTH_OIDC_UUID_000000000000000000001"/>
<column name="obj_version" valueNumeric="0"/>
<column name="client_id" value="auth-experimental"/>
<column name="client_name" value="auth-experimental"/>
<column name="client_secret" value="$2a$11$GmswBlCAZ9dtY5sS9DE.OOWJqzDGiwjh2eRDTflHAPcpIXhnkNlfK"/>
<column name="client_authentication_methods" value="client_secret_post,client_secret_basic"/>
<column name="authorization_grant_types" value="refresh_token,authorization_code"/>
<column name="scopes" value="openid"/>
<column name="client_settings"
value='{"@class":"java.util.Collections$UnmodifiableMap","settings.client.require-proof-key":false,"settings.client.require-authorization-consent":false}"'/>
<column name="token_settings"
value='{"@class":"java.util.Collections$UnmodifiableMap","settings.token.reuse-refresh-tokens":true,"settings.token.id-token-signature-algorithm":["org.springframework.security.oauth2.jose.jws.SignatureAlgorithm","RS256"],"settings.token.access-token-time-to-live":["java.time.Duration",300.000000000],"settings.token.access-token-format":{"@class":"org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat","value":"self-contained"},"settings.token.refresh-token-time-to-live":["java.time.Duration",3600.000000000],"settings.token.authorization-code-time-to-live":["java.time.Duration",300.000000000]}'/>
<column name="redirect_uris"
value="http://keycloak.hvlnet.net:8080/auth/realms/may/broker/oidc/endpoint"/>
</insert>
<insert tableName="kys_oidc_client">
<column name="id" valueSequenceNext="KYS_OIDC_CLIENT_SEQ"/>
<column name="created_by" value="unknown"/>
<column name="created_at" valueDate="CURRENT_TIMESTAMP"/>
<column name="updated_at" valueDate="CURRENT_TIMESTAMP"/>
<column name="updated_by" value="unknown"/>
<column name="uuid" value="ADMIN_MON_OIDC_UUID_0000000000000001"/>
<column name="obj_version" valueNumeric="0"/>
<column name="client_id" value="javalt-admin-monitor"/>
<column name="client_name" value="javalt-admin-monitor"/>
<column name="client_secret" value="$2a$11$81MUNYM95rfUoF6oWiSPN.wxuVhWqjIpaE5ecjPifBGz6RkHxpg2i"/>
<column name="client_authentication_methods" value="client_secret_post,client_secret_basic"/>
<column name="authorization_grant_types" value="refresh_token,authorization_code"/>
<column name="scopes" value="openid,profile"/>
<column name="client_settings"
value='{"@class":"java.util.Collections$UnmodifiableMap","settings.client.require-proof-key":false,"settings.client.require-authorization-consent":false}"'/>
<column name="token_settings"
value='{"@class":"java.util.Collections$UnmodifiableMap","settings.token.reuse-refresh-tokens":true,"settings.token.id-token-signature-algorithm":["org.springframework.security.oauth2.jose.jws.SignatureAlgorithm","RS256"],"settings.token.access-token-time-to-live":["java.time.Duration",300.000000000],"settings.token.access-token-format":{"@class":"org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat","value":"self-contained"},"settings.token.refresh-token-time-to-live":["java.time.Duration",3600.000000000],"settings.token.authorization-code-time-to-live":["java.time.Duration",300.000000000]}'/>
<column name="redirect_uris"
value="http://hvlapp.hvlnet.net:2323/login/oauth2/code/keysis-oidc"/>
</insert>
</changeSet>
OIDC Kullanıcısı Güncelleme#
<changeSet author="sgunes" id="20240613-1">
<update tableName="kys_oidc_client">
<column name="client_id_issued_at" valueDate="CURRENT_TIMESTAMP"/>
<column name="client_secret_expires_at" valueDate="CURRENT_TIMESTAMP"/>
<where>uuid = 'ADMIN_MON_OIDC_UUID_0000000000000001'</where>
</update>
</changeSet>
<changeSet author="sgunes" id="20240613-2">
<update tableName="kys_oidc_client">
<column name="client_id_issued_at" valueDate="CURRENT_TIMESTAMP"/>
<column name="client_secret_expires_at" valueDate="CURRENT_TIMESTAMP"/>
<where>uuid = 'AUTH_OIDC_UUID_000000000000000000001'</where>
</update>
</changeSet>