Keycloak Logout with SAML - saml

I got a problem with logout using saml protocol in Keycloak Server 4.2.1.
Next to the Keycloak there is a Wildfly 9 server. In the Wildfly Server there
are serveral .war files deployed. They are JSF Applications with JEE7.
I configured the saml adapter (keycloak-saml.xml) like this. Similiar to the documetation
(https://www.keycloak.org/docs/latest/securing_apps/index.html#_saml-general-config)
<keycloak-saml-adapter>
<SP entityID="amp"
sslPolicy="EXTERNAL"
logoutPage="logout.jsp">
<Keys>
<Key signing="true">
<PrivateKeyPem>
...CLIENT PRIVATE KEY...
</PrivateKeyPem>
<CertificatePem>
...CLIENT CERTIFICATE ...
</CertificatePem>
</Key>
</Keys>
<PrincipalNameMapping policy="FROM_ATTRIBUTE"/>
<IDP entityID="idp"
signatureAlgorithm="RSA_SHA256"
signatureCanonicalizationMethod="http://www.w3.org/2001/10/xml-exc-c14n#">
<SingleSignOnService signRequest="true"
validateResponseSignature="true"
requestBinding="POST"
bindingUrl="http://localhost:8080/auth/realms/My-Realm/protocol/saml"/>
<SingleLogoutService signRequest="true"
signResponse="true"
validateRequestSignature="true"
validateResponseSignature="true"
requestBinding="POST"
responseBinding="POST"
postBindingUrl="http://localhost:8080/auth/realms/My-Realm/protocol/saml"
redirectBindingUrl="http://localhost:8080/auth/realms/My-Realm/protocol/saml"/>
<Keys>
<Key signing="true">
<CertificatePem>
... REALM CERTIFICATE ...
</CertificatePem>
</Key>
</Keys>
</IDP>
</SP>
</keycloak-saml-adapter>
When i click the "logout button" the application calls
the code below so that the Wildfly server invalidate the session.
((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest()).logout();
((HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(false)).invalidate();
I checked it and its working, the application is invalidate the session.
Now after that, i have to tell the keycloak server that he should invalidate this session too.
Which URL I have to call?
FacesContext.getCurrentInstance().getExternalContext().redirect(" ???? ");
Before I migrated to Keycloak Server 4.2.1, I had the older version 1.8.1 running.
With the 1.8.1 Server I called the URL
"http://localhost:8080/auth/realms/My-Realm/tokens/logout?redirect_uri=http://localhost:8180/amp".
But that is not working anymore.
I have tested serveral URL but none of them are working. I checked the latest
documetation https://www.keycloak.org/docs/latest/securing_apps/index.html#logout-2
and the parameter GLO=true is not working either.
I also tried to configure "Logout Service POST Binding URL" and "Logout Service Redirect Binding URL"
for the client in the keycloak adminstration console.
Did i miss something in code or adminstration console of keycloak?
Do i have to call a specific url in keycloak 4.2.1?
If you need more informations, let me know.
Thanks for your help.
kind regards.

Keycloak provides a single SAML endpoint, namely 'https://{host}/auth/realms/{realm}/protocol/saml', to which you have to send the SAML logout request. In your client SAML configuration, you either have to setup the "Master SAML Processing URL" pointing to your application's SAML endpoint, or you have to explicitly configure the "Logout Service Redirect Binding URL" if you have a special SAML endpoint for Single Logout in your application.

Related

Keycloak IDP Keycloak broker Login to java-saml application

While trying to achieve pure Keycloak IDP initiated sso to achieve this flow
"Login to keycloak realm ==> Go to applications ==> click on application name and application launches because you are already logged in to the keycloak IDP),
I faced several issues while trying to achieve the above flow, so I gave that up, and now trying to achieve Keycloak brokered sso:
(Browse to the specific Keycloak broker URL ==> Get redirected to the login page of the Keycloak IDP ==> this does a POST of Saml assertion to my application URL ==> Application launches because the user is already logged in / authenticated with IDP).
I am using one instance of Keycloak as IDentity provider (keycloak3) and another instance as Service Provider (keycloak4).
I am following the steps from this existing thread.
idp initiated sso using keycloak
########## Start Steps followed ##########
a. create a saml client at keycloak3 (http://localhost:8083) under realm3. With IdP initiated SSO Name set as some name without spaces) --> say, sso.
b. In the Fine Grain SAML Endpoint Configuration section of the above client, for Assertion Consumer Service (ASC) POST Binding URL --> http://localhost:8084/realms/realm4/broker/saml/endpoint/clients/keycloak4samlclient ( https://www.keycloak.org/docs/latest/server_admin/index.html#idp-initiated-login)
c. click on above created saml client --> installation --> Export SAML Metadata IDPSSODescriptor and save as saml-metadata.xml ( say ).
d. Add a user in keycloak3, say user3/user#456
e. At the keycloak4(http://localhost:8084), create a IDP ( identity providers tab with name saml (refer ASC url). Import the above exported saml-metadata.xml and save.
f. At the keycloak4, create a saml client and in the IDP initiated SSO url give name as keycloak4samlclient
g. In the browser hit, http://localhost:8083/realms/realm3/protocol/saml/clients/sso
Prompt for username/pwd, give credentials for user3
########## End Steps followed ##########
My application is the 'java-saml' application deployed on local tomcat at 8080.
https://github.com/SAML-Toolkits/java-saml/tree/master/samples/java-saml-tookit-jspsample
After I complete all the steps, and browse this URL
http://localhost:8083/realms/realm3/protocol/saml/clients/sso
I am getting "client not found" error. I spent the entire day troubleshooting this one, could not find any leads. Can someone please let me know if you have faced this, and whether you have any solution I can try? This is the screenshot of error.
Error Message: Client not found

Keycloak SAML IdP gives invalidFederatedIdentityActionMessage after login

I configured a SAML identity provider in keycloak by importing metadata provided by Microsoft ADFS.
I could see the option of IdP on my client login page for login.
After clicking on that on that button it redirects to external identity provider login page.
After login, I get success with a SAMLResponce. (Checked with SAML tracer).
The page is redirected to IDP redirect URL.
After redirecting page shows me "invalidFederatedIdentityActionMessage"
I saw the docker logs it gives me ---
23:58:09,035 WARN [org.keycloak.events] (default task-181) type=IDENTITY_PROVIDER_RESPONSE_ERROR, realmId=rak-development, clientId=null, userId=null, ipAddress=172.18.0.4, error=invalid_saml_response, reason=invalid_destination
Can you please help what I am doing wrong.
This happens when you configure the Identity Provider to 'Validate Signature'. When you turn that switch on, Keycloak validates the SAML response against the text in 'Validating X509 Certificates'. That field should contain a valid certificate from your Identity Provider; in this case the App registration in Microsoft.
Try turning the 'Validate Signature' switch off to see if that removes the error. Then you can debug the certificate value.
I had a similar problem and it turned out to be a misconfiguration of the F5 proxy/firewall. It sent the wrong header "X-Forwarded-Proto: http" instead of "X-Forwarded-Proto: https". Maybe this can help.
I found a solution. For me, the issue was that I needed to set the PROXY_ADDRESS_FORWARDING=true envvar. I had already done that but I typoed the name.
I am using the AWS ALB which sets the X-Forwarded headers. I know those are also needed.

Keycloak integration with Pingfederate

What I want to do is this:
I have keycloak integrated with my application. So when my app is launched , keycloak login page is shown to user. Now , I am trying to provide an option to login with PingFedrate. So a button to login with PingFed appears(once a new SAML provider is configured in keycloak). On PingFedrate I tried to integrate SP inititated SSO:
I added a new SP connection and there I configured it as SSP initiated SSO. (It forced me to configure SOAP Authentication , where I selected basic and configured random username password). Then I downloaded metatdata.xml from this SP and imported in keycloak which autofilled the login url as : https://myserver:9031/idp/SSO.saml2 (i.e. without client id). After this when user clickon Login with PingFed - PingFed gives following error:
Unexpected System Error Sorry for the inconvenience. Please contact
your administrator for assistance and provide the reference number
below to help locate and correct the problem.
I found the solution to this.
Firstly, we need to add SP inititated SSO in Pingfed for keycloak.
Secondly, the reason I could not make SP inititated SSO work was that keycloak's entityId should be same as Pingfed SP connection's Partner's Entity Id / Connection Id.
Keycloak, by default keeps entity id equal to url of keyloak server containing your realm. E.g
https://(keycloak-server)/auth/realms/(realm-name)
(and I could not find a way to change it through Keycloak UI)
You need to enter this URL in Pingfed.
To avoid adding this manually, you can download the keycloak config from download export tab of identity provider.
And on Pingfed , import this file.
On a side note, though I was importing it earlier, I was changing value of Partenr id to some other name as I was not aware of above restriction until I started decoding the SAML tokens in request.

Authentication Info to Backend Service

I have a situation, wherein, I have integrated, WSO2APIM, Identity Server, Microsoft ADFS2.0. Configured successfully so that MSADFS is acting as IdP, APIM acting as SP (with /publisher) as a service. Configuration worked fine when accessed(/publisher of APIM), ADFS presented LogonPage, all necessary SAML2.0 exchanges happened perfect and final page (/publisher) presented.
Now, the actual situation is, instead of accessing APIM service (/publisher), I need to access a POST Rest URL(Eg. APIMIP:Port/vendors/payments). This API is configured to hit backend API (Eg. BEIP:Port/vendors/payments).
1. In above situation, I need to pass the SAML authentication information or any other authorized info to actual BE, somehow.
2. How to achieve it.

Accessing REST service after login within browser using oauth2 and spring security using java config

I have implemented Oauth2 using sparkl2 app. I am using spring-security as described in the sparkl2 app using java config. I can successfully get auth token using curl and i can invoke web service using curl.
My question is
How I can access my REST service within the same browser after login into my application? I am not sure what I am missing here?
Let me elaborate my question in more details. The way browser keep session after login and we can access any protected resource in the application, what is the best way to implement so that I can test my REST api from browser
spring security keeps it in session. Session id is stored in browser cookie, so its passed with each request to your service. Then spring security should take it and check if specific session(with user logged in) is allowed to hit this particular url.
I would start with configuring secure paths in your java config:
http.authorizeRequests().antMatchers().hasAnyRole(...)
or some other method instead antMatchers.
you probably have to log in user into spring security on some oauth callback, something like:
Authentication auth = new UsernamePasswordAuthenticationToken(user, null, authorities);
SecurityContextHolder.getContext().setAuthentication(auth);