我正在尝试建立以下架构,但很困难:
带有此图像 jboss/keycloak:7.0.0 的 Keycloak 容器
带有 mod_auth_openidc 的 Apache
apache 有一个受保护的目录
Apache 有一个 SSL 客户端 Authent
我想要配置以下场景:
用户访问 mywebsite/demo
Apache 提示他使用证书进行身份验证
Apache 将信息转发给 keycloak
Keycloak 使用 X509/Validate Username 来验证证书(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 容器,我不确定如果我安装它而不是默认容器是否会考虑我的 standalone.xml,因此我执行了以下 jboss 命令:
/子系统 = keycloak 服务器 / spi = x509cert-lookup:写入属性 (名称 = 默认提供程序,值 =“apache”) /子系统=keycloak服务器/spi=x509cert-lookup/provider=apache:write-attribute(name=properties.sslClientCert,value="SSL_CLIENT_CERT") /子系统 = keycloak 服务器 /spi = x509cert-lookup/provider = apache: write-attribute (name = properties.sslCertChainPrefix,value =“CERT_CHAIN”) /子系统 = keycloak 服务器 /spi = x509cert-lookup/provider = apache: write-attribute (name = properties.certificateChainLength,值 =“10”) :重新加载
我的 keycloak 配置如下:客户端重定向:
身份验证流程:
但是当我以用户“Team XYZ”和证书 CN“Team XYZ”的身份访问该网站时,出现此错误:
{"error_description":"X509 client certificate is missing.","error":"invalid_request"}
Keycloak 日志:
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'