简体   繁体   中英

Saml setup with Keycloak as Identity Broker and Okta as Identity provider not working

I am using keycloak (version 8.0.1) as an identity broker in my application. I've setup the saml integration between keycloak/okta as specified in this blog, https://ultimatesecurity.pro/post/okta-saml/

I also have a sample application that I am using to test this integration which is from this blog, https://scalac.io/user-authentication-keycloak-1

I am running into an issue when okta redirects back to keycloak. The response from okta is successful however on receiving the response keycloak looks at the KC_RESTART cookie and tries to find a kid in the JWT which is encoded in that cookie but does not find a match and throws the following exception,

19:26:00,581 DEBUG [org.keycloak.jose.jws.DefaultTokenManager] (default task-1) Failed to decode token: org.keycloak.common.VerificationException: Key not found
    at org.keycloak.crypto.ServerMacSignatureVerifierContext.getKey(ServerMacSignatureVerifierContext.java:31)
    at org.keycloak.crypto.ServerMacSignatureVerifierContext.<init>(ServerMacSignatureVerifierContext.java:25)
    at org.keycloak.crypto.MacSecretSignatureProvider.verifier(MacSecretSignatureProvider.java:39)
    at org.keycloak.jose.jws.DefaultTokenManager.decode(DefaultTokenManager.java:94)
    at org.keycloak.protocol.RestartLoginCookie.restartSession(RestartLoginCookie.java:146)
    at org.keycloak.services.resources.SessionCodeChecks.restartAuthenticationSessionFromCookie(SessionCodeChecks.java:376)
    at org.keycloak.services.resources.SessionCodeChecks.initialVerifyAuthSession(SessionCodeChecks.java:197)
    at org.keycloak.services.resources.SessionCodeChecks.initialVerify(SessionCodeChecks.java:204)
    at org.keycloak.services.resources.IdentityBrokerService.parseSessionCode(IdentityBrokerService.java:1027)
    at org.keycloak.services.resources.IdentityBrokerService.parseEncodedSessionCode(IdentityBrokerService.java:1016)
    at org.keycloak.services.resources.IdentityBrokerService.authenticated(IdentityBrokerService.java:501)
    at org.keycloak.broker.saml.SAMLEndpoint$Binding.handleLoginResponse(SAMLEndpoint.java:485)
    at org.keycloak.broker.saml.SAMLEndpoint$Binding.handleSamlResponse(SAMLEndpoint.java:524)

I have also enabled TRACE logging on keycloak and I see the following error message being printed in the logs,

Before exception,

19:32:19,019 TRACE [org.keycloak.keys.DefaultKeyManager] (default task-1) Failed to find public key: realm=MyDemo kid=5a148511-021f-477d-a716-2f0f2d425d12 algorithm=HS256 use=SIG

After exception

19:32:19,021 TRACE [org.keycloak.events] (default task-1) type=IDENTITY_PROVIDER_LOGIN_ERROR, realmId=MyDemo, clientId=null, userId=null, ipAddress=127.0.0.1, error=invalid_code, requestUri=http://localhost:8080/auth/realms/MyDemo/broker/samlokta/endpoint, cookies=[io=URgKM5wjPjr8WQdlAAAA, JSESSIONID=57782504027A376E7FD18A7F061B7225, KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI1YTE0ODUxMS0wMjFmLTQ3N2QtYTcxNi0yZjBmMmQ0MjVkMTIifQ.eyJjaWQiOiJhY2NvdW50IiwicHR5Ijoib3BlbmlkLWNvbm5lY3QiLCJydXJpIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL2F1dGgvcmVhbG1zL015RGVtby9hY2NvdW50L2xvZ2luLXJlZGlyZWN0IiwiYWN0IjoiQVVUSEVOVElDQVRFIiwibm90ZXMiOnsic2NvcGUiOiJvcGVuaWQiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvTXlEZW1vIiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJjb2RlX2NoYWxsZW5nZV9tZXRob2QiOiJwbGFpbiIsInJlZGlyZWN0X3VyaSI6Imh0dHA6Ly9sb2NhbGhvc3Q6ODA4MC9hdXRoL3JlYWxtcy9NeURlbW8vYWNjb3VudC9sb2dpbi1yZWRpcmVjdCIsInN0YXRlIjoiMC9mMjBkNTU4ZS00M2I0LTRkMjEtOTFlYy0xOGY0YmQzYmE0OWMifX0.Y0zN-c33soimR_JhvTex-nRKL0rZKquOhRtfdofrF-A, AUTH_SESSION_ID=e549d547-0bd0-413e-986c-361bb35ead4c.moizs-mbp, OAuth_Token_Request_State=6d9150e4-fb5f-45c9-bda5-3a042d964e4c]

Looking at the code in DefaultKeyManager.java it appears that the kid which is in the KC_RESTART cookie could not be found in the KeyProvider.

I need help figuring out why not, I'm not sure what step I am missing. Any help would be appreciated.

        for (KeyProvider p : getProviders(realm)) {
            for (KeyWrapper key : p.getKeys()) {
                if (key.getKid().equals(kid) && key.getStatus().isEnabled() && matches(key, use, algorithm)) {
                    if (logger.isTraceEnabled()) {
                        logger.tracev("Found key: realm={0} kid={1} algorithm={2} use={3}", realm.getName(), key.getKid(), algorithm, use.name());
                    }

                    return key;
                }
            }
        }

As it turns out this was a configuration issue. So, basically I am running keycloak on localhost for testing. So I had started it up on localhost and configured the IDP on keycloak. After I configured the IDP I exported the metadata and imported it into Okta. At this point the Audience URI and the Response URI etc. got imported with localhost as the host name. After fiddling around I changed both the URIs to use 127.0.0.1 as host name instead of localhost and that fixed the issue.

I got a clue that this might be a problem when I tried integrating with PingId. PingId rejected the AuthenticationRequest because the entityId - derived from the URI was not matching. I'm not quite sure what the issue with keycloak is but I wanted to post this answer for others who may be stuck with a similar problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM