Table of Contents

Сервис Keycloak

Установка и запуск

Bare metal

server# wget https://github.com/keycloak/keycloak/releases/download/22.0.5/keycloak-22.0.5.zip

server:~/keycloak-22.0.5# KEYCLOAK_ADMIN=root KEYCLOAK_ADMIN_PASSWORD='strongpassword' bin/kc.sh start-dev --https-certificate-file=/root/server.crt --https-certificate-key-file=/root/server.key

docker-compose

cp /root/wild.crt /etc/ssl/certs/
cp /root/wild.key /etc/ssl/private/

chmod 750 /etc/ssl/private/
chmod 640 /etc/ssl/private/wild.key
chgrp -R student /etc/ssl/private/

mkdir -p /opt/keycloak/data/
chown -R student /opt/keycloak/

###chgrp student /etc/krb5.keytab
###chmod 640 /etc/krb5.keytab

###cat /opt/keycloak/themes/mytheme/login/theme.properties
parent=keycloak

###cat /opt/keycloak/themes/mytheme/login/messages/messages_en.properties
usernameOrEmail=Login
loginAccountTitle=OpenID SSO CorpX

# cat keycloak.yml
version: '3'

services:
  keycloak:
    image: quay.io/keycloak/keycloak:22.0.5
    container_name: keycloak
    restart: always
    user: 1000:1000
    ports:
      - 80:8080
      - 443:8443
    volumes:
      - "/etc/ssl/certs/wild.crt:/wild.crt:"
      - "/etc/ssl/private/wild.key:/wild.key"
      - "/opt/keycloak/data/:/opt/keycloak/data/"
      #- "/opt/keycloak/themes/:/opt/keycloak/themes/"
      #- "/etc/krb5.keytab:/etc/krb5.keytab"
    environment:
      - KEYCLOAK_ADMIN=root
      - KEYCLOAK_ADMIN_PASSWORD=strongpassword
      - KC_HTTPS_CERTIFICATE_FILE=/wild.crt
      - KC_HTTPS_CERTIFICATE_KEY_FILE=/wild.key
    command:
      - start-dev
# docker-compose -f keycloak.yml up -d

# docker logs keycloak -f

Kubernetes

~/$ helm repo add bitnami https://charts.bitnami.com/bitnami; helm search repo bitnami/keycloak --versions; helm repo remove bitnami

~/$ mkdir keycloak; cd keycloak

~/keycloak$ ###helm pull oci://registry-1.docker.io/bitnamicharts/keycloak --version 17.3.6

~/keycloak$ helm template my-keycloak oci://registry-1.docker.io/bitnamicharts/keycloak --version 17.3.6 | tee keycloak.yaml | less
/PersistentVolumeClaim
~/keycloak$ helm show values oci://registry-1.docker.io/bitnamicharts/keycloak --version 17.3.6 | tee values.yaml.orig
			  
~/keycloak$ cat values.yaml
auth:
  adminUser: admin
  adminPassword: strongpassword
proxy: edge
#proxyHeaders: "xforwarded"
ingress:
  enabled: true
  ingressClassName: nginx
  hostname: keycloak.corp13.un
#global:
#  storageClass: local-path
#  storageClass: longhorn
#replicaCount: 2
#postgresql:
#  enabled: true
#  auth:
#    postgresPassword: "strongpassword"
#    username: bn_keycloak
#    password: "strongpassword"

#extraVolumeMounts:
#- mountPath: /opt/bitnami/keycloak/themes
#  name: themes
#extraVolumes:
#- emptyDir: {}
#  name: themes

#initContainers:
#- name: get-theme
#  image: curlimages/curl
#  command: ["/bin/sh", "-c"]
#  args:
#  - |
#    cd /opt/bitnami/keycloak/themes/
#    curl https://val.bmstu.ru/unix/Media/mytheme.tgz | tar -xvzf -
#  securityContext:
#    runAsUser: 1001
#  volumeMounts:
#  - mountPath: /opt/bitnami/keycloak/themes
#    name: themes
~/keycloak$ ###helm template my-keycloak -f values.yaml oci://registry-1.docker.io/bitnamicharts/keycloak -n my-keycloak-ns --version 17.3.6 | less

~/keycloak$ helm upgrade my-keycloak -i -f values.yaml oci://registry-1.docker.io/bitnamicharts/keycloak -n my-keycloak-ns --create-namespace --version 17.3.6

~/keycloak$ kubectl -n my-keycloak-ns get pods -o wide --watch

~/keycloak$ curl -v http://nodeN/ -H "Host: keycloak.corp13.un"

~/keycloak$ ###kubectl -n my-keycloak-ns exec -ti my-keycloak-postgresql-0 -- psql -U postgres

$ ###helm delete my-keycloak -n my-keycloak-ns
$ ###kubectl delete ns my-keycloak-ns

Подключение

Базовая конфигурация

Create Realm->corpX
  Users
    Add User
      user1/kcpassword1
      В новых версиях надо ФИО и email, иначе Account is not fully set up

Страница для проверки учетных записей

Аутентификация пользователей WEB приложения

Clients     
  Create Client
  
    Client ID: test-cgi
    Valid redirect URIs: http://gate.corpX.un/cgi-bin/test-cgi
или
    Client ID: any-client
    Valid redirect URIs: *

Проверка

curl

webinar# curl -d "client_id=any-client" \
     -d "client_secret=anystring" \
     -d "grant_type=password" \
     -d "username=user1" \
     -d 'password=kcpassword1' \
     https://keycloak.corp13.un/realms/corp13/protocol/openid-connect/token
     
{"access_token":"..." ...

Apache CGI приложение

Подключение БД пользователей

Kerberos

User federation
  Kerberos
    UI display name: CORPX
    Kerberos realm: CORPX.UN
    Server principal: HTTP/server.corpX.un@CORPX.UN
    Key tab: /etc/krb5.keytab
    Allow password authentication: yes

Authentication
  browser
    Kerberos: Disabled 
      (иначе появляется всплывающее окно аутентификации, можно оставить если пользователи в домене)
      

LDAP

Active Directory

Vendor: Active Directory

Connection URL: ldap://server

Bind type: simple
Bind DN: cn=Administrator,cn=Users,dc=corpX,dc=un
Bind credentials: ...

Edit mode: READ_ONLY      #WRITABLE for add minio attributes
Users DN: cn=Users,dc=corpX,dc=un
Username LDAP attribute: sAMAccountName
...
Mappers ->
  username ->
    LDAP Attribute: sAMAccountName

OpenLDAP

Vendor: Other

Connection URL: ldap://server

Bind type: none
Edit mode: READ_ONLY

Users DN: ou=People,dc=corpX,dc=un
...
UUID LDAP attribute: uid

+ Kerberos

пока не заработало

Kerberos principal attribute: uid
Use Kerberos for password authentication: yes

Добавление атрибутов

MinIO

<code>
Client scopes: Create client scores

  Name: minio-authorization
  Save

  Mappers
    Configure a new mapper
      User Attribute
        Name: minio-policy-mapper
        User Attribute: policy
        Token Claim Name: policy
        Multivalued: On
        Aggregate attribute values: On

Clients
  any-client
    Client scopes
      Add client scopes
        minio-authorization
        Add->Default

Users
  user2
    Attributes
      Add an attribute
        Key: policy
        Value: readwrite
  

Дополнительные материалы

API

debian:~# cat keycloak.sh
#!/bin/bash

#export KEYCLOAK_URL=https://portal.bmstu.ru
export KEYCLOAK_URL=https://portal-demo.bmstu.ru
export KEYCLOAK_REALM=ph
export KEYCLOAK_CLIENT_ID=superuser
export KEYCLOAK_CLIENT_SECRET=XXXXXXXXXXXXXXXXXXXX
#export USER_ID=391530c1-c4f2-4838-bb95-def2c8e37e57

export TKN=$(curl -X POST "${KEYCLOAK_URL}/auth/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token" \
 -d "username=${KEYCLOAK_CLIENT_ID}" \
 -d "password=${KEYCLOAK_CLIENT_SECRET}" \
 -d 'grant_type=password' \
 -d 'client_id=ph-master' | jq -r '.access_token')

echo $TKN

#curl -vvv -X GET "${KEYCLOAK_URL}/auth/admin/realms/${KEYCLOAK_REALM}/users/${USER_ID}" \
curl -vvv -X GET "${KEYCLOAK_URL}/auth/admin/realms/${KEYCLOAK_REALM}/users/?q=username:ivanovii" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${TKN}" | jq .

K8S

kube1:~/keycloak# diff keycloak.yaml keycloak.yaml.orig
457,458c457
< #kind: StatefulSet
< kind: Deployment
---
> kind: StatefulSet
472,476c471,475
< #  podManagementPolicy: Parallel
< #  serviceName: my-keycloak-headless
< #  updateStrategy:
< #    rollingUpdate: {}
< #    type: RollingUpdate
---
>   podManagementPolicy: Parallel
>   serviceName: my-keycloak-headless
>   updateStrategy:
>     rollingUpdate: {}
>     type: RollingUpdate