Keycloak x.509 인증서 인증

Keycloak x.509 인증서 인증

다음 아키텍처를 설정하려고 하는데 어려움을 겪고 있습니다.

  • 이 이미지가 포함된 Keycloak 컨테이너 jboss/keycloak:7.0.0

  • mod_auth_openidc를 사용하는 Apache

  • 아파치에는 보호된 디렉토리가 있습니다

  • Apache는 SSL 클라이언트 인증을 수행합니다.

다음 시나리오를 구성하고 싶습니다.

  • 사용자가 mywebsite/demo를 방문합니다.

  • Apache는 인증서로 인증하라는 메시지를 표시합니다.

  • Apache는 정보를 keycloak으로 전달합니다.

  • Keycloak은 X509/Validate 사용자 이름을 사용하여 인증서(CN)의 유효성을 검사합니다.

  • 인증되면 사용자에게 리소스를 반환합니다.

Apache vhost에 대해 다음 구성이 있습니다.

Listen 8081 https
<VirtualHost *:8081>

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html/

        SSLEngine on
        SSLCipherSuite HIGH
        SSLProtocol all -SSLv3 -TLSv1.3


        SSLCertificateFile /etc/apache2/ssl/serv.crt
        SSLCertificateKeyFile /etc/apache2/ssl/serv.key
        SSLCACertificateFile /etc/apache2/ssl/ca.crt

        <Location /pdf >
                ProxyPass http://mywebsite:5001/pdf
                ProxyPassReverse http://mywebsite:5001/pdf
        </Location>
        #RequestHeader set CERT_CHAIN ""
        RequestHeader set  SSL_CLIENT_CERT ""


        OIDCCryptoPassphrase passphrase
        OIDCProviderMetadataURL https://mywebsite:9004/auth/realms/demorealm/.well-known/openid-configuration
        OIDCClientID demo2
        OIDCClientSecret e6dc781f-49c0-4cfa-9cde-411f9d8bc2cb
        OIDCSSLValidateServer Off
        OIDCRedirectURI https://mywebsite:9998/demo2/redirect
        OIDCRemoteUserClaim preferred_username
        OIDCInfoHook access_token id_token userinfo session


        <Location /demo2 >

                SSLVerifyClient require
                SSLVerifyDepth 2
                #RequestHeader set SSL_CLIENT_CERT_CHAIN_0 "%{{CERT_CHAIN}}s"
                RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s"
                #Require ssl


                AuthType openid-connect
                Require valid-user
                Loglevel debug
        </Location>

</VirtualHost>

keycloak 컨테이너의 경우 컨테이너가 기본값 대신 내 독립형.xml을 마운트하는 경우 이를 고려하는지 확신할 수 없으므로 다음 jboss 명령을 실행했습니다.

   /subsystem=keycloak-server/spi=x509cert-lookup:write-attribute(name=default-provider, value="apache")
   /subsystem=keycloak-server/spi=x509cert-lookup/provider=apache:write-attribute(name=properties.sslClientCert,value="SSL_CLIENT_CERT")
   /subsystem=keycloak-server/spi=x509cert-lookup/provider=apache:write-attribute(name=properties.sslCertChainPrefix,value="CERT_CHAIN")
   /subsystem=keycloak-server/spi=x509cert-lookup/provider=apache:write-attribute(name=properties.certificateChainLength,value="10")
   :다시 로드

내 keycloak은 다음과 같이 구성됩니다. 클라이언트 리디렉션:

클라이언트 리다이렉트

인증 흐름은 다음과 같습니다.

실행

구성 실행 인증자

하지만 웹 사이트를 방문하면 인증서 CN "Team XYZ"를 사용하는 "Team XYZ" 사용자로서 다음 오류가 발생합니다. {"error_description":"X509 client certificate is missing.","error":"invalid_request"}

키클로크 로그:

21:10:24,178 WARN  [org.keycloak.services.x509.AbstractClientCertificateFromHttpHeadersLookup] (default task-49) HTTP header "SSL_CLIENT_CERT" is empty

20:09:48,062 WARN  [org.keycloak.events] (default task-9) type=LOGIN_ERROR, realmId=5c005f6f-a912-4788-bf53-345551eb0e01, clientId=demo2, userId=null, ipAddress=Dummy, error=user_not_found, auth_method=openid-connect, auth_type=code, response_type=code, redirect_uri=https://mywebsite:9998/demo2/redirect, code_id=d2b3aecf-0a53-4d3a-85fd-3433aee61d61, response_mode=query, authSessionParentId=d2b3aecf-0a53-4d3a-85fd-3433aee61d61, authSessionTabId=FqOsf6BrEBk

누군가 저를 도와주세요. 저는 며칠 동안 이 문제에 봉착했습니다.

답변1

kubernetes 환경에서는 다음 솔루션이 작동합니다.

      nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
      nginx.ingress.kubernetes.io/proxy-ssl-secret: "mynamespace/backend-x509-secret"
      nginx.ingress.kubernetes.io/proxy-ssl-verify: "on"
      nginx.ingress.kubernetes.io/proxy-ssl-verify-depth: "2"

      nginx.ingress.kubernetes.io/auth-tls-secret: "mynamespace/backend-x509-secret"
      nginx.ingress.kubernetes.io/auth-tls-verify-client: "optional"
      nginx.ingress.kubernetes.io/auth-tls-verify-depth: "2"
      nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "true"

여기서 mynamespace/backend-x509-secret은 kustomization.yaml에서 생성됩니다.

secretGenerator:
- name: backend-x509-secret
  files:
  - tls.crt
  - tls.key
  - ca.crt

여기서 tls.crt,tls.key,ca.crt는 내 소유의 자체 서명이고 CA 인증서는 keycloak X509 인증에 사용되는 반면 내 nginx는 Let's encrypt 인증서를 사용하고 있습니다.
그런 다음 keycloak 구성 파일standalone.xml 또는standalone-ha.xml은 시작 시 다음 cli 파일로 업데이트됩니다.

/subsystem=keycloak-server/spi=x509cert-lookup:write-attribute(name=default-provider, value="nginx")            
/subsystem=keycloak-server/spi=x509cert-lookup/provider=default:remove
/subsystem=keycloak-server/spi=x509cert-lookup/provider=nginx:add(enabled=true,properties={sslClientCert => "ssl-client-cert", sslCertChainPrefix => "USELESS",     certificateChainLength => "2"})            

다음을 사용하여 keycloak 구성을 동적으로 변경할 수도 있습니다.

$JBOSS_HOME/bin/jboss-cli.sh --connect --command='/subsystem=keycloak-server/spi=x509cert-lookup:write-attribute(name=default-provider, value="nginx")'            
$JBOSS_HOME/bin/jboss-cli.sh --connect --command='/subsystem=keycloak-server/spi=x509cert-lookup/provider=default:remove'
$JBOSS_HOME/bin/jboss-cli.sh --connect --command='/subsystem=keycloak-server/spi=x509cert-lookup/provider=nginx:add(enabled=true,properties={ sslClientCert => "ssl-client-cert", sslCertChainPrefix => "USELESS", certificateChainLength => "2"})'           
$JBOSS_HOME/bin/jboss-cli.sh --connect --command=':reload'

관련 정보