KeyCloak

Resul Rzayev
6 min readJan 7, 2022

Keycloak daha az kodla ve daha asan yolla muasir application ve servislerinizi secure etmeyi hedefleyen, open source Identity ve Access management tooldur. 2018-ci ilde Jboss Community terefinden Red Hat-in desteyi ile yaradilib.

Keycloak

Single-Sign-On/Out (SSO), Identity Brokering — OpenDdConnect , SAML qosulma,Social Login — google, twitter, facebook ve.s, User Federation (ldap ve active directory desteyi), Client Adapters, Admin Console,

Account Management Console ve.s kimi imkanlari da verir. OIDC (openId connect) protokolu uzerinden Java ucun bir cox adapterler verir (Spring Boot, Spring Security, Jboss, Tomcat ve.s ucun). tam siyahini asagidaki linkden baxa bilersiniz oz documentation-indan :

*** Single-Sign-On/Out (SSO) nedir ? Sade misalla izah etsek google hesabiniza neceki single sign olmaqla butun gmail, youtube ve.s diger google accountunza bagli saytlara tekrar sign in tekrar istemeden hemin hesabla login olursunuzsa bax bu yanasma SSO adlanir.

Install edilmesi ( standalone , docker ):

standalone install
docker install

KeyCloak istifade etmezden evvel admin hesab olmalidir ve bu hesabla GUI-den admin console-a daxil ola bilersiniz. Daxil olduqda bele bir sehife ile qarsilasacaqsiniz:

keycloak home page

Daxil olmusunuzsa artiq master realmda isleyrisiniz, hansiki realm ozu obyektleri manage etmek ucun bir spacedir. Keycloakda iki tip realm movcuddur :

master realm— login oldugumuz admin accountunun da yer aldigi realmdir. Diger realmlarin yaradilmasi da bu realmdan bas verir eslinde

other realms — bu hemin admin userla master realmda yaratdigimiz diger realmlardir

Eger admin userle yeni realm elave etmek isteyirikse master->add realm vururuq ve ad teyin edib create edirik. Hemin vaxt keycloak ozu redirect edecek yaradilan realma interfeysimizde. Amma istesez admin userle girib yeni user create edib ve manage rollari map edib username password teyin edib onunla giris edib de realm ve.s yarada bilersiniz.

Ve artiq realmimiz varsa next step realmda custom clientlerimizi yarada bilerik:

Keycloak terefinden default yaranmis clientlar

Client-ler servislerimizin secure olmasini temin edib, token temin etmekden hokumludurler.

Add client edib hemin realmda yeni clientimizi yaradaq. Access type-imizi secirik (Bu barede detalli irelide yazmisam) Valid Redirect URLs kimi appimizde istifade edeceyimiz url-i teyin edirik. Access Type -i Confidential ve Bearer-only sececeksinizse token alacaqsiniz demekdir ve buna gore Service Accounts Enabled switch on edin.

Daha sonra access type publicden ferqli secseniz oreceknsiniz credentials tab yaranacaq ve oradan yer alan secret id ile uygun credentiallarla openid endpointlerinden token almaq ucun ./openid-connect/token -e sorgu gonderib tokeni ala bilkersiniz:

OpenId Connect endpoints
token almaq ucun sorgu

client-secret : buna clientinizin credentials tabindan generate ederek ala bilersiniz

client_id: ele client name-dir

username & password : bunlari user yaradanda credentials tabinda set edirsiniz

grant_type : eger password secirsinizse sizde username password required isteyecek requestde keycloakda yaratdiginiz useri n!!!

Eger client_credentials secirsinizse user ve pass ehtiyac olmayacaq gondermeye.

*** credentials tab-da password ucun temporary enabled-dirse sizde details-den actionlardan “update password”-i silin eks halda token ala bilmyeceksiniz…

Token-imizi verify edib

***Token almaq ucun muraciet ederken diqqet edin ki token qayitsa da jwt.io-da verify edib response duzgun formalasmasina baxin cliente uygun accesslerin yerinde olmasina baxin !!!

Eger token expire olubsa hemin url-e yeniden ancaq bu defe refresh token-i de requeste elave ederek gonderirik :

{
'client_id': 'your_client_id',
'refresh_token': refresh_token_from_previous_request,
'grant_type': 'refresh_token'
}
Token configuration
client installation OIDCN json format

Token muddetini ve diger parametrlerin deyisdirilmesi ucun realmda token tabindan baxa bilersiniz configlere.

Ve daha sonra installation tab click edib OIDC json ve ya xml ve.s tipinde secib export edib download ede bilersiniz ve application yml-inizde copy edib istifade ede bilersiniz.

Eger refresh token de qaytarmasini isteyirikse bunun ucun compability mode-a girib use refresh tokens for client credentials grant true edirik

Gorduyunuz kimi access type 3-curdur, ferqleri ise documentationda cox izah edici sekilde aciqlanmisdir :

Confidential: which is used for applications that need to perform browser login, and the client will get the access token through client secret, mostly used in web systems rendered by the server.

Public: for applications that need to perform browser login, mostly used in front-end projects implemented using vue and react.

Bearer-only: for applications that don’t need to perform browser login, only allow access with bearer token, mostly used in RESTful API scenarios.

*** Bearer only secseniz openid-connect/token ile token ala bilmezsiniz!!! Cunki bearer-only bunun ucun nezerde tutulmayib. Bele izah edek 2 mikroservisimiz varsa ve A-ms. B-ms i cagirirsa cagiran teref confidential olur token alir gonderir cagrilan teref ise bearer-only olur ve java terefde adapterde config edilir tokenle isleyir. Ve hec bir login page falan da olmur.

*** public secirsinizse redirect url-e diqqet edin!

*** confidential ve ya bearer secsek elave credentials tab yarandigini goreceksiniz. secret id ve client id orada yer alir.

Keycloak butun bu datalari embedded H2 databasede saxlayir. Eger postgre-de ve ya mysql-de database yaradib oraya qosmaq isteyirsinizse stepler asagidaki linkde izah edilib :

https://www.tutorialsbuddy.com/keycloak-postgresql-setup

https://dev.to/donadams50/connect-mysql-server-to-keycloak-3d6e

Spring Boot-da inteqrasiyasi

  • keycloak-spring-boot-starter dependency-sini elave etmelisiniz:
  • application-properties faylinde uygun configinizi elave edin, meselem:
keycloak:
realm: My-Realm
auth-server-url: http://localhost:8080/auth
resource: my-client-1
credentials:
secret: PKQI2sqQAjneaGDl6yJfRQRyXk20JJNg
bearer-only: true

#certificate trust etmek ucun
#don't use below configs on prod env

disable-trust-manager: true
allow-any-hostname: false
# Bu confige diqqet edin eger siz permissiomlari realm role uzerinden vereceksinizse false , client role uzerinden edeceksinizse true vermelisiniz !!!
use-resource-role-mappings: true
use-resource-role-mappings
  • Keycloakin spring security config ucun verdiyi adapter olan KeycloakWebSecurityConfigurerAdapter -ni tetbiq edin:
  • Controllerinizde login page atib role yoxlamaq istediyiniz servis uzerine @PreAuthorize @PostAuthorize @RolesAllowed kimi annotationlarla elave edib permission config ede bilersiniz. Hemcinin annotation evezine KeycloakSecurityConfig clasinizda cinfigure metodunda da ozunuz endpointler ucun hasAnyRole ile permissionlari teyin ede bilersiniz.

@PreAuthorize(“hasRole(‘admin’)”)

@RolesAllowed({ “admin”, “user” })

*** yuxaridaki anotasiyalar aktiv olmasi ucun @EnableGlobalMethodSecurity(prePostEnabled = true) bunu security config clasiniza elave etmeyi unutmayin!

token header-e bearer elave edirsiniz ve access var deye ok-dur
Access yoxdursa 403 forbidden verecek

Eger bearer-only istifade edirsinizse ve bunu Zuul ve.s kimi gatewayde etmek isetyirsinizse burada zuul bearer-only qosulur ve token verify edib rollari security contexte elave edib ms-lerinize gonderir hansisa header key-le , bunu etmek ucun asagidaki kimi bir kod parcasi istifade etmelisniz evvelce gatewayinizde :

get token roles and add to security context

Ve ms-lerde OncePerRequestFilter elave edib bunu security configinizde addFilterBefore edib hemin client rollara gore @PreAuthorize(hasRole) istfde ede bilersiniz :

--

--