Custom SPI for OIDC-to-SAML Broker

Hello,

I’m planning to connect my SP (OIDC) client to a SAML IDP through Keycloak SAML Broker.
I have got zero control on the SAML IDP, but full on Keycloak/broker and the SP/OIDC client.
My problem is:

#1 The SAML IDP is fully trusted for my use-case, but it responds with a Token carried in the Subject of SAML response (inside the saml2:NameID which is persistent) and also in a another attribute/claim (same token).

#2 The token should be sent back in the response to OIDC client, then client should POST it to a different API to finally get the actual user attributes.

I have no interest in creating/importing the IDP users into broker/Keycloak, however, to store the IDP token carried in SAML response I thought to map the attribute/claim (which carries the token) to a user attribute, then remove the user entries regularly from my Keycloak User Storage. This works fine, but:

#3 Obviously it seems that it doesn’t make sense to store tokens with such length in Keycloak’s MySQL column USERNAME in USER_ENTITY table (SAML NameID == identity_provider_identity). So, I had another idea where I should generate a shorter Username from that token, store the user and the token as a user attribute, then the client would get the SAML token from Keycloak/Broker Userinfo endpoint.

#4 I need to skip the login (User/Pass) step in the 1st Broker Login flow, but I’m not good in Java, and have tried by best to understand the Custom Authenticator implementation with no luck – couldn’t find some guides or so.
My ultimate goal is for SAML token to reach the OIDC client.

I assume my problems (#3 & 4) would require a custom Authentication SPI/Flow, but I’m open to any suggestion indeed.

Looking forward for kind help.

Regards,
-Bobby

Hi, I have a new idea. I’ll go with the “Create if Unique” flow, and create the user this way;
1- Set the username to userID from UserModel
2- calling success on the AuthenticationFlowContext.

Could you please help on how to achieve the points above.

Thank you!

Hello,

I’m sharing my progress here, yet I’m looking for a kind help!

Found an authentication script here MCPKeycloakSpi/NoPromptAuthenticatorJS.js at master · maritimeconnectivity/MCPKeycloakSpi · GitHub

The script was made to achieve what I’m looking for, create a unique user from IDP, then authenticate.
With few modifications (hardcoding username/email… as I dont want to store any user basically, but just wanted to override the system architecture, then send the IDP’s SAML response to OIDC client.
But, after all that, the script fails because; creating the user in “FEDERATED_IDENTITY” MySQL table is not possible (value is too long). So, below is what happens. Could you please help if there is anyway to override the “identity_provider_identity” value which results in this issue.

PS: I know this may sound like an awkward tweak, but I really have no other options.
NOTE: I’m on Keycloak 11.0.2

18:31:50,520 INFO [org.keycloak.authentication.authenticators.browser.ScriptBasedAuthenticator] (default task-13) No duplication detected. Creating account for user ‘:test’ and linking with identity provider: saml
18:31:50,548 INFO [org.keycloak.authentication.authenticators.browser.ScriptBasedAuthenticator] (default task-13) null
18:31:50,554 INFO [org.keycloak.authentication.authenticators.browser.ScriptBasedAuthenticator] (default task-13) Auth success! :smiley:
18:31:50,648 WARN [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-13) SQL Error: 1406, SQLState: 22001
18:31:50,648 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-13) Data truncation: Data too long for column ‘FEDERATED_USER_ID’ at row 1
18:31:50,649 WARN [org.keycloak.events] (default task-13) type=IDENTITY_PROVIDER_LOGIN_ERROR, realmId=IAMPROXY, clientId=debug, userId=49adc67f-6360-4f63-a806-67034aa0300b, ipAddress=5.163.168.165, error=identityProviderUnexpectedErrorMessage, identity_provider=saml, identity_provider_identity=##########LONG TOKEN VALUE##########, code_id=e20e4be1-36d2-4683-af71-d1a41a24dbc8, username=ahmed, authSessionParentId=e20e4be1-36d2-4683-af71-d1a41a24dbc8, authSessionTabId=2_NvQTpCUSo
18:31:50,649 ERROR [org.keycloak.services.resources.IdentityBrokerService] (default task-13) identityProviderUnexpectedErrorMessage: org.keycloak.models.ModelException: javax.persistence.PersistenceException: org.hibernate.exception.DataException: could not execute statement
at org.keycloak.connections.jpa.PersistenceExceptionConverter.convert(PersistenceExceptionConverter.java:61)
at org.keycloak.connections.jpa.PersistenceExceptionConverter.invoke(PersistenceExceptionConverter.java:51)