到目前为止,我已经从RPM安装中使用Keycloak一段时间了,没有任何问题。现在,我们将大多数服务迁移到Openshift集群(3.9)中。在将Keycloak迁移到当前服务器(4.8.3)的最新版本之前,我正在Openshift Cluster中进行全新安装,这是问题所在。
我正在Openshift集群中使用官方映像 jboss / keycloak:latest ,并且POD已启动并正在运行。但是每次我尝试访问securtiy-admin-console时,无论我使用哪种浏览器,成功登录后都会进入无限循环。
到目前为止,这是我得到的: -访问security-admin-console https://keycloak.openshift.cluster/auth/admin/master/console/#/进入重定向循环。
访问用户帐户https://keycloak.openshift.cluster/auth/realms/master/account正常。
在浏览器控制台中,登录过程中没有错误,但是当应用程序尝试刷新令牌时,出现了400错误请求。一旦我已经有了令牌并且已经登录并且Keycloak尝试刷新会话,就会出现此错误。 。
此后,我在日志中收到此错误:
17:20:06,765 DEBUG [org.keycloak.authentication.AuthenticationProcessor] (default task-8) AUTHENTICATE CLIENT
17:20:06,765 DEBUG [org.keycloak.authentication.ClientAuthenticationFlow] (default task-8) client authenticator: client-secret
17:20:06,765 DEBUG [org.keycloak.authentication.ClientAuthenticationFlow] (default task-8) client authenticator SUCCESS: client-secret
17:20:06,765 DEBUG [org.keycloak.authentication.ClientAuthenticationFlow] (default task-8) Client security-admin-console authenticated by client-secret
17:20:06,765 DEBUG [org.keycloak.jose.jws.DefaultTokenManager] (default task-8) Failed to decode token: org.keycloak.jose.jws.JWSInputException: java.lang.IllegalArgumentException: Parsing error
at org.keycloak.jose.jws.JWSInput.<init>(JWSInput.java:58)
at org.keycloak.jose.jws.DefaultTokenManager.decode(DefaultTokenManager.java:63)
at org.keycloak.protocol.oidc.TokenManager.toRefreshToken(TokenManager.java:370)
at org.keycloak.protocol.oidc.TokenManager.verifyRefreshToken(TokenManager.java:336)
at org.keycloak.protocol.oidc.TokenManager.refreshAccessToken(TokenManager.java:254)
at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.refreshTokenGrant(TokenEndpoint.java:462)
at org.keycloak.protocol.oidc.endpoints.TokenEndpoint.processGrantRequest(TokenEndpoint.java:185)
at sun.reflect.GeneratedMethodAccessor499.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:140)
at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:509)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:399)
at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:363)
at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:365)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:337)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:137)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:106)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:132)
at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:100)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:443)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:233)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:139)
at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:358)
at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:142)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:219)
at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
at org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:90)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:68)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at org.wildfly.extension.undertow.security.SecurityContextThreadSetupAction.lambda$create$0(SecurityContextThreadSetupAction.java:105)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1502)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1502)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1502)
at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1502)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:360)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1985)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1487)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1378)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: Parsing error
at org.keycloak.jose.jws.JWSInput.<init>(JWSInput.java:45)
... 76 more
17:20:06,766 WARN [org.keycloak.events] (default task-8) type=REFRESH_TOKEN_ERROR, realmId=master, clientId=security-admin-console, userId=null, ipAddress=XXX.XXX.XXX.XXX, error=invalid_token, grant_type=refresh_token, client_auth_method=client-secret
17:20:06,766 DEBUG [org.keycloak.services.resources.Cors] (default task-8) Added CORS headers to response
17:20:06,766 DEBUG [org.keycloak.services.resources.Cors] (default task-8) Added CORS headers to response
17:20:06,766 DEBUG [org.keycloak.services.resources.Cors] (default task-8) Added CORS headers to response
我创建了多个用户,并且始终具有相同的行为。
在ADMIN-CLI上一切正常,我可以登录并执行admin-cli允许的任何操作。
在我们的网络中,默认情况下会阻止所有不带TLS / SSL的流量,因此我们正在使用配置为边缘的路由器并重定向非安全流量。
关于部署/ POD配置,按照docker容器的说明,我将以下环境变量添加到Keycloak部署中:
我检查了一下,Openshift路由器默认添加了正确的标题,这些标题是:
这是Keycloak POD的路由器配置:
mode http
option redispatch
option forwardfor
balance leastconn
timeout check 5000ms
http-request set-header X-Forwarded-Host %[req.hdr(host)]
http-request set-header X-Forwarded-Port %[dst_port]
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header Forwarded for=%[src];host=%[req.hdr(host)];proto=%[req.hdr(X-Forwarded-Proto)]
cookie *************************** insert indirect nocache httponly secure
server pod:keycloak-50-k75pr:keycloak:XXX.XXX.XXX.XXX:8080 XXX.XXX.XXX.XXX:8080 cookie ***************************** weight 256 check inter 5000ms
我唯一要做的修改是将Openshift集群的CA证书添加到容器的cacert中。
我的主领域配置是默认配置,但这是内容:
[ {
"id" : "master",
"realm" : "master",
"displayName" : "Keycloak",
"displayNameHtml" : "<div class=\"kc-logo-text\"><span>Keycloak</span></div>",
"notBefore" : 0,
"revokeRefreshToken" : false,
"refreshTokenMaxReuse" : 0,
"accessTokenLifespan" : 60,
"accessTokenLifespanForImplicitFlow" : 900,
"ssoSessionIdleTimeout" : 1800,
"ssoSessionMaxLifespan" : 36000,
"ssoSessionIdleTimeoutRememberMe" : 0,
"ssoSessionMaxLifespanRememberMe" : 0,
"offlineSessionIdleTimeout" : 2592000,
"offlineSessionMaxLifespanEnabled" : false,
"offlineSessionMaxLifespan" : 5184000,
"accessCodeLifespan" : 60,
"accessCodeLifespanUserAction" : 300,
"accessCodeLifespanLogin" : 1800,
"actionTokenGeneratedByAdminLifespan" : 43200,
"actionTokenGeneratedByUserLifespan" : 300,
"enabled" : true,
"sslRequired" : "external",
"registrationAllowed" : false,
"registrationEmailAsUsername" : false,
"rememberMe" : true,
"verifyEmail" : false,
"loginWithEmailAllowed" : true,
"duplicateEmailsAllowed" : false,
"resetPasswordAllowed" : false,
"editUsernameAllowed" : false,
"bruteForceProtected" : false,
"permanentLockout" : false,
"maxFailureWaitSeconds" : 900,
"minimumQuickLoginWaitSeconds" : 60,
"waitIncrementSeconds" : 60,
"quickLoginCheckMilliSeconds" : 1000,
"maxDeltaTimeSeconds" : 43200,
"failureFactor" : 30,
"defaultRoles" : [ "uma_authorization", "offline_access" ],
"requiredCredentials" : [ "password" ],
"passwordPolicy" : "hashIterations(20000)",
"otpPolicyType" : "totp",
"otpPolicyAlgorithm" : "HmacSHA1",
"otpPolicyInitialCounter" : 0,
"otpPolicyDigits" : 6,
"otpPolicyLookAheadWindow" : 1,
"otpPolicyPeriod" : 30,
"otpSupportedApplications" : [ "FreeOTP", "Google Authenticator" ],
"browserSecurityHeaders" : {
"contentSecurityPolicyReportOnly" : "",
"xContentTypeOptions" : "nosniff",
"xRobotsTag" : "none",
"xFrameOptions" : "SAMEORIGIN",
"xXSSProtection" : "1; mode=block",
"contentSecurityPolicy" : "frame-src 'self'",
"strictTransportSecurity" : "max-age=31536000; includeSubDomains"
},
"smtpServer" : { },
"eventsEnabled" : false,
"eventsListeners" : [ "jboss-logging" ],
"enabledEventTypes" : [ ],
"adminEventsEnabled" : false,
"adminEventsDetailsEnabled" : false,
"internationalizationEnabled" : false,
"supportedLocales" : [ ],
"browserFlow" : "browser",
"registrationFlow" : "registration",
"directGrantFlow" : "direct grant",
"resetCredentialsFlow" : "reset credentials",
"clientAuthenticationFlow" : "clients",
"dockerAuthenticationFlow" : "docker auth",
"attributes" : {
"_browser_header.xXSSProtection" : "1; mode=block",
"_browser_header.xFrameOptions" : "SAMEORIGIN",
"_browser_header.strictTransportSecurity" : "max-age=31536000; includeSubDomains",
"permanentLockout" : "false",
"quickLoginCheckMilliSeconds" : "1000",
"displayName" : "Keycloak",
"_browser_header.xRobotsTag" : "none",
"maxFailureWaitSeconds" : "900",
"minimumQuickLoginWaitSeconds" : "60",
"displayNameHtml" : "<div class=\"kc-logo-text\"><span>Keycloak</span></div>",
"failureFactor" : "30",
"actionTokenGeneratedByUserLifespan" : "300",
"maxDeltaTimeSeconds" : "43200",
"_browser_header.xContentTypeOptions" : "nosniff",
"offlineSessionMaxLifespan" : "5184000",
"actionTokenGeneratedByAdminLifespan" : "43200",
"_browser_header.contentSecurityPolicyReportOnly" : "",
"bruteForceProtected" : "false",
"_browser_header.contentSecurityPolicy" : "frame-src 'self'",
"waitIncrementSeconds" : "60",
"offlineSessionMaxLifespanEnabled" : "false"
},
"userManagedAccessAllowed" : false
} ]
我总是尝试从干净的环境重新安装多次,结果总是相同,这是访问主控制台的循环。即使在特权模式下运行POD /容器,结果也相同。
有人可以帮我检查我做错了什么吗?
非常感谢。
答案 0 :(得分:0)
我希望您使用了正确的模板。如果未使用正确的模板,则可能会遇到HTTPS重定向问题。而且,您不能简单地在Pod的端口8080上使用HTTPS。端口8080仅用于HTTP通信。
https://github.com/jboss-dockerfiles/keycloak/blob/master/openshift-examples/keycloak-https.json
谢谢。
答案 1 :(得分:0)
有没有机会使用Redis或其他会话缓存机制?
在具有多个前端网关的环境中使用密钥转换时,会启动an issue in jboss about infinite redirects。 link to a solution in another bug也张贴在此处。
答案 2 :(得分:0)
模板创建的路由的 TLS 终止类型为 re-encrypt
。我们将其更改为 passthrough
并且有效。