Openshift /密钥斗篷4.8.3。登录到管理控制台无限重定向循环

时间:2019-03-04 18:12:15

标签: jboss openshift keycloak openshift-origin jboss-tools

到目前为止,我已经从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正常。 Keycloak Account access working fine

  • 在浏览器控制台中,登录过程中没有错误,但是当应用程序尝试刷新令牌时,出现了400错误请求。一旦我已经有了令牌并且已经登录并且Keycloak尝试刷新会话,就会出现此错误。 Bad Request Error Authentication error

此后,我在日志中收到此错误:

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部署中:

  • PROXY_ADDRESS_FORWARDING = true
  • KEYCLOAK_USER = admin
  • KEYCLOAK_PASSWORD = ******
  • DB_ADDR = postgres.openshift.cluster
  • DB_PORT = 5432
  • DB_DATABASE = keycloak
  • DB_USER = keycloak
  • DB_PASSWORD = ******
  • KEYCLOAK_HOSTNAME = keycloak-it

我检查了一下,Openshift路由器默认添加了正确的标题,这些标题是:

  • X转发主机
  • X-Forwarded-Proto
  • X转发端口

这是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 /容器,结果也相同。

有人可以帮我检查我做错了什么吗?

非常感谢。

3 个答案:

答案 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 redirectslink to a solution in another bug也张贴在此处。

答案 2 :(得分:0)

模板创建的路由的 TLS 终止类型为 re-encrypt。我们将其更改为 passthrough 并且有效。

相关问题