[keycloak-user] SAML in a keycloak cluster

Stian Thorgersen sthorger at redhat.com
Wed Oct 26 09:06:11 EDT 2016


This is standard proxy stuff. It uses Host header and X-Forwarded-*. You
need to make sure that X-Forwarded-* headers are included and that the
original Host header is passed on.

On 26 October 2016 at 11:21, GKAZGKAS Dimitrios (TAN/MST) <
Dimitrios.Gkazgkas at tangoservices.lu> wrote:

> Hello Stian,
>
>
>
> Thank you for this hint and your help in general. Indeed you are right the
> URLs in the specified path returns security1 or security2 (Loadbalanced)
> and not security.lu.
>
>
>
>   *<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://mojito-security2.lu:8080/realms/master/protocol/saml
> <http://mojito-security2.lu:8080/realms/master/protocol/saml>"/>*
>
> *<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://mojito-security2.lu:8080/realms/master/protocol/saml
> <http://mojito-security2.lu:8080/realms/master/protocol/saml>"/>*
>
> *<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="http://mojito-security2.lu:8080/realms/master/protocol/saml
> <http://mojito-security2.lu:8080/realms/master/protocol/saml>"/>*
>
> *<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://mojito-security2.lu:8080/realms/master/protocol/saml
> <http://mojito-security2.lu:8080/realms/master/protocol/saml>"/>*
>
> *<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://mojito-security2.lu:8080/realms/master/protocol/saml
> <http://mojito-security2.lu:8080/realms/master/protocol/saml>"/>*
>
>
>
> But our backend servers + the reverse proxy are configured according to
> specs + some rewrites. You can see our EAP and proxy configuration at the
> end of this messsage. The principal issue is that the backend servers are
> not able to understand themselves as *security.lu <http://security.lu>*
> but frankly I do not know how this could work as *we have nowhere
> configuration in the individual keykloack servers (EAP 7 + k*
> eycloak-overlay-1.9.8*) that reference the public name “security.lu
> <http://security.lu>”. *The *only machine* that knows the “security.lu”
> is the *RP *(apache + mod_proxy) which is hosted in another server.
> Could you explain how the individual Keycloak servers should automatically
> understand thay they are seen as “security.lu”  from the outisde  ???
>
>
>
> What would be more logical is that the backend keycloack servers do have a
> configuration to know which other keycloack servers are on the same cluster
> and use this list as white-list to serve request regardless if the
> destination is security1 or security2 ….
>
>
>
>
>
> =============Standalone-ha XML config=======
>
>
>
> <subsystem xmlns="urn:jboss:domain:undertow:3.1"
> instance-id="mojitosecurity1">
>
>             <buffer-cache name="default"/>
>
>             <server name="default-server">
>
>                 <ajp-listener name="ajp" socket-binding="ajp"/>
>
>                 <http-listener name="default" proxy-address-forwarding="true"
> socket-binding="http" redirect-socket="proxy-https"/>
>
>                 <host name="default-host" default-web-module="keycloak-server.war"
> alias="localhost">
>
>                     <filter-ref name="server-header"/>
>
>                     <filter-ref name="x-powered-by-header"/>
>
>                     <filter-ref name="proxy-peer"/>
>
>                 </host>
>
>             </server>
>
>             <servlet-container name="default">
>
>                 <jsp-config/>
>
>                 <websockets/>
>
>             </servlet-container>
>
>             <handlers>
>
>                 <file name="welcome-content" path="${jboss.home.dir}/
> welcome-content"/>
>
>             </handlers>
>
>             <filters>
>
>                 <response-header name="server-header" header-name="Server"
> header-value="JBoss-EAP/7"/>
>
>                 <response-header name="x-powered-by-header"
> header-name="X-Powered-By" header-value="Undertow/1"/>
>
>                 <filter name="proxy-peer" module="io.undertow.core"
> class-name="io.undertow.server.handlers.ProxyPeerAddressHandler"/>
>
>             </filters>
>
>         </subsystem>
>
> …..
>
>
>
> <interfaces>
>
>         <interface name="management">
>
>             <inet-address value="${jboss.bind.address.
> management:x.x.x.x.}"/>
>
>         </interface>
>
>         <interface name="public">
>
>             <inet-address value="${jboss.bind.address:192.168.xxx.xxx}"/>
>
>         </interface>
>
>         <interface name="private">
>
>             <inet-address value="${jboss.bind.address.
> private:192.168.xxx.xxx}"/>
>
>         </interface>
>
>     </interfaces>
>
>
>
>     <socket-binding-group name="standard-sockets"
> default-interface="public" port-offset="${jboss.socket.
> binding.port-offset:0}">
>
>         <socket-binding name="management-http" interface="management"
> port="${jboss.management.http.port:xxxxx}"/>
>
>         <socket-binding name="management-https" interface="management"
> port="${jboss.management.https.port:xxxx}"/>
>
>         <socket-binding name="ajp" port="${jboss.ajp.port:xxxx}"/>
>
>         <socket-binding name="http" port="${jboss.http.port:xxxx}"/>
>
>         <socket-binding name="https" port="${jboss.https.port:xxxx}"/>
>
>         <socket-binding name="jgroups-mping" interface="private" port="0"
> multicast-address="${jboss.default.multicast.address:xxx.x.x.x}" mu
>
> lticast-port="xxxxxx"/>
>
>         <socket-binding name="jgroups-tcp" interface="private"
> port="xxxxx"/>
>
>         <socket-binding name="jgroups-tcp-fd" interface="private" port="
> xxxxx "/>
>
>         <socket-binding name="jgroups-udp" interface="private" port="
> xxxxx " multicast-address="${jboss.default.multicast.address: xxx.x.x.x }"
>
> multicast-port="45688"/>
>
>         <socket-binding name="jgroups-udp-fd" interface="private" port="
> xxxxx "/>
>
>         <socket-binding name="modcluster" port="0" multicast-address="
> xxx.x.x.xxx" multicast-port="xxxxx"/>
>
>         <socket-binding name="txn-recovery-environment" port="xxxx"/>
>
>         <socket-binding name="txn-status-manager" port="xxxx"/>
>
>         <socket-binding name="proxy-https" port="xxx"/>
>
>         <outbound-socket-binding name="mail-smtp">
>
>             <remote-destination host="localhost" port="xx"/>
>
>         </outbound-socket-binding>
>
>     </socket-binding-group>
>
>
>
> =============RP config===========
>
>
>
> <VirtualHost *:443>
>
>         ProxyRequests off
>
>         ServerName security.lu
>
>         SSLEngine On
>
>         SSLProtocol ALL -SSLv2 -SSLv3
>
>         SSLCipherSuite xxxxxxxxxxxxxxxx;
>
>         SSLHonorCipherOrder on
>
>         <Proxy *>
>
>                 AddDefaultCharset Off
>
>                 Order deny,allow
>
>                Allow from all
>
>         </Proxy>
>
>
>
>         <Proxy balancer://securitycluster>
>
>                 BalancerMember http://mojito-security1.lu:8080
> route=mojitosecurity1
>
>                 BalancerMember http://mojito-security2.lu:8080
> route=mojitosecurity2
>
>                 Order Deny,Allow
>
>                 Deny from none
>
>                 Allow from all
>
>                 # By default, ProxySet lbmethod=byrequests
>
>                 # ProxySet stickysession=ROUTEID
>
>         </Proxy>
>
>         <Location /balancer-manager>
>
>                 SetHandler balancer-manager
>
>                 # I recommend locking this one down to your
>
>                 # your office
>
>                 Order deny,allow
>
>                 Allow from 172.25.240.0/21
>
>         </Location>
>
>          ProxyPass /balancer-manager !
>
>          ProxyPass / balancer://securitycluster/ stickysession=JSESSIONID|
> jsessionid
>
>        RewriteEngine on
>
>
>
>         <Location /realms/Tango/protocol/openid-connect>
>
>         RewriteRule "/auth\?redirect_uri=https://facture\.lu/(.*)"
> "/realms/Tango/protocol/openid-connect/auth\?redirect_uri=http://billing2
> \.lu/$1"
>
>         Header edit Location http://billing2.lu https://facture.tango.lu
>
>         </Location>
>
>         <Location /realms/Tango/protocol/saml>
>
>         Header edit Location ^http://mojito-security1.lu:8080
> https://security.lu
>
>         Header edit Location ^http://mojito-security2.lu:8080
> https://security.lu <https://security.tango.lu>
>
>         </Location>
>
>
>
>
>
>         ErrorLog "/opt/csw/apache2/var/log/error_security.lu.log"
>
>         TransferLog "/opt/csw/apache2/var/log/access_security.lu.log"
>
> </VirtualHost>
>
>
>
>
>
>
>
>   Br
>
>
>
> Dimitrios Gkazgkas
>
> IT Solutions Architect
>
> ............................................................
> ..................................
>
>
>
>
>
> *From:* Stian Thorgersen [mailto:sthorger at redhat.com]
> *Sent:* 20 October 2016 13:20
>
> *To:* GKAZGKAS Dimitrios (TAN/MST) <Dimitrios.Gkazgkas at tangoservices.lu>
> *Cc:* keycloak-user at lists.jboss.org; Benoît Reny <benoit.reny at its4u.lu>
> *Subject:* Re: [keycloak-user] SAML in a keycloak cluster
>
>
>
> Check the urls in http://security.lu/auth/realms/master/protocol/saml/
> descriptor. The URLs should contain security.lu and not URLs for the
> individual nodes. If that's not working, then you don't have the reverse
> proxy parts configured correctly.
>
>
>
> On 20 October 2016 at 11:47, GKAZGKAS Dimitrios (TAN/MST) <
> Dimitrios.Gkazgkas at tangoservices.lu> wrote:
>
> Hello,
>
>
>
> This part of the configuration (Identifying Client IP Addresses" as well
> as "Enable HTTPS/SSL with a Reverse Proxy") is already in place in our
> system but still it does not work.
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>   Br
>
>
>
> Dimitrios Gkazgkas
>
> IT Solutions Architect
>
> ............................................................
> ..................................
>
>
>
>
>
> *From:* Stian Thorgersen [mailto:sthorger at redhat.com]
> *Sent:* 19 October 2016 16:12
> *To:* GKAZGKAS Dimitrios (TAN/MST) <Dimitrios.Gkazgkas at tangoservices.lu>
> *Cc:* keycloak-user at lists.jboss.org; Benoît Reny <benoit.reny at its4u.lu>
>
>
> *Subject:* Re: [keycloak-user] SAML in a keycloak cluster
>
>
>
> Hm.. Just reviewing that doc and it's not far from obvious.
>
>
>
> "Identifying Client IP Addresses" as well as "Enable HTTPS/SSL with a
> Reverse Proxy" are both relevant.
>
>
>
> On 19 October 2016 at 15:51, GKAZGKAS Dimitrios (TAN/MST) <
> Dimitrios.Gkazgkas at tangoservices.lu> wrote:
>
> Hello,
>
>
>
> I suppose that you are talking about the part :
> Using the Built-In Load Balancer
>
>
>
> The thing is that if i understand well is that we can do this
> configuration for a domain clustered mode. Our configuration is currently a
> standalone clustered mode. This configuration can be also applied in this
> case ?
>
>
>
> Thanks for your reply,
>
>
>
>
>
>
>
>
>
>
>
>
>
>   Br
>
>
>
> Dimitrios Gkazgkas
>
> IT Solutions Architect
>
> ............................................................
> ..................................
>
>
>
>
>
> *From:* Stian Thorgersen [mailto:sthorger at redhat.com]
> *Sent:* 19 October 2016 14:36
>
>
> *To:* GKAZGKAS Dimitrios (TAN/MST) <Dimitrios.Gkazgkas at tangoservices.lu>
> *Cc:* keycloak-user at lists.jboss.org
> *Subject:* Re: [keycloak-user] SAML in a keycloak cluster
>
>
>
> If you configure your reverse proxy correct as well as configure it on the
> Keycloak side. Keycloak will see it's URL as security.lu and not the URL
> used by the reverse proxy to access it. The steps to do this is explained
> in the documentation I sent you.
>
>
>
> On 19 October 2016 at 14:29, GKAZGKAS Dimitrios (TAN/MST) <
> Dimitrios.Gkazgkas at tangoservices.lu> wrote:
>
> ======Sent again without the picture=====
>
>
>
> Hello,
>
>
>
> Could you please be more specific ?
>
>
>
> In the documentation proposed  it is referred how to FW the original
> client IP  but our problem seems to be  the Destination (IDP) inside the “samlp:AuthnRequest”.
>
>
>
>
>
>
> We get the following error:
>
> 2016-10-11 14:52:10,152 WARN  [org.keycloak.events] (default task-2)
> type=LOGIN_ERROR, realmId=xxx, clientId=null, userId=null, ipAddress=xxxx,
> error=invalid_authn_request, reason=invalid_destination
>
> It seems to come from the following part of the code of Keycloack project.
>
>
>
> package org.keycloak.protocol.saml;
>
> public class SamlService extends AuthorizationEndpointBase
>
>
>
> *protected Response loginRequest(String relayState, AuthnRequestType
> requestAbstractType, ClientModel client) {*
>
> *            SamlClient samlClient = new SamlClient(client);*
>
> *            // validate destination*
>
> *            if (requestAbstractType.getDestination() != null &&
> !uriInfo.getAbsolutePath().equals(requestAbstractType.getDestination())) {*
>
> *                event.detail(Details.REASON, "invalid_destination");*
>
> *                event.error(Errors.INVALID_SAML_AUTHN_REQUEST);*
>
> *                return ErrorPage.error(session,
> Messages.INVALID_REQUEST);*
>
> *            }*
>
>
>
> The destination check simply do not much , request destination is always
> the internal keyclaock address  “security1.lu” and it fails when saml
> requests end up to the second keycloack “securty2.lu”.
>
>
>
>
>
>
>
>
>
>   Br
>
>
>
> Dimitrios Gkazgkas
>
> IT Solutions Architect
>
> ............................................................
> ..................................
>
>
>
>
>
> *From:* Stian Thorgersen [mailto:sthorger at redhat.com <sthorger at redhat.com>]
>
> *Sent:* 18 October 2016 20:12
>
> *To:* GKAZGKAS Dimitrios (TAN/MST) <Dimitrios.Gkazgkas at tangoservices.lu>
> *Cc:* keycloak-user at lists.jboss.org
> *Subject:* Re: [keycloak-user] SAML in a keycloak cluster
>
>
>
> Please look at the documentation. It explains this.
>
>
>
> On 18 October 2016 at 16:57, GKAZGKAS Dimitrios (TAN/MST) <
> Dimitrios.Gkazgkas at tangoservices.lu> wrote:
>
> Hello Stian,
>
>
>
> Thank you for your response.
>
>
>
> Could you explain a bit more what you mean by saying “*as Keycloak should
> see security.lu <http://security.lu>, not the internal addresses of the
> nodes*”  ?  According to our understanding the Keycloak servers  in the
> internal network is behind reverse proxy and thus they do not know that
> they are called “security.lu”, they just know that they are either
> security1.lu or security2.lu <http://security1.lu>.
>
>
>
> When we tried to overwite the  Saml XML configuration (that client uses
> for integration) and put  the public address “security.lu” we again had
> the same ERROR in Keycloak logs “reason=invalid_destination” probably due
> to same root cause, the destination in the Saml AuthRequest was
> “Service.lu”, an address unknown for keycloack inside the private network.
>
> <samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
> Destination="
>
>
>
> I  attach our HA configuration. We do not use the build in Load Balancer
> but an Appache Reverse Proxy which actually rewrites all internall URLs to
> Publics for outgoing trafiif and the oposite for the incoming traffic. Thus
> there is not much left in the page you sent to be configured in our
> Keycloak.
>
>
>
> I hope I was clear. Any help would  be highly appreciated.
>
>
>
>   Br
>
>
>
> Dimitrios Gkazgkas
>
> IT Solutions Architect
>
> ............................................................
> ..................................
>
>
>
>
>
> *From:* Stian Thorgersen [mailto:sthorger at redhat.com]
> *Sent:* 17 October 2016 20:41
> *To:* GKAZGKAS Dimitrios (TAN/MST) <Dimitrios.Gkazgkas at tangoservices.lu>
> *Cc:* keycloak-user at lists.jboss.org
> *Subject:* Re: [keycloak-user] SAML in a keycloak cluster
>
>
>
> Sounds like you haven't setup things properly as Keycloak should see
> security.lu, not the internal addresses of the nodes. Take a look at
> https://keycloak.gitbooks.io/server-installation-and-
> configuration/content/topics/clustering/load-balancer.html
>
>
>
> On 13 October 2016 at 19:14, GKAZGKAS Dimitrios (TAN/MST) <
> Dimitrios.Gkazgkas at tangoservices.lu> wrote:
>
> The response from the list on my initial mails was : After content
> filtering, the message was empty
>
> So I try to send the same mail without CC and without attached
>
>
>
> ===========
>
> Hello,
>
> We are trying to configure a SAML authentication system in a keycloak
> cluster. First, with only one node , we are currently managing to
> authenticate in SAML way.
>
> The architecture :
> --> we have one apache reverse proxy with a public and unique endpoint for
> saml authentication. We can call the pubic url : security.lu<
> http://security.lu>
>
> --> the reverse proxy will load-balance all calls that come on security.lu
> <http://security.lu> to two keycloak nodes : security1.lu<
> http://security1.lu> and security2.lu<http://security2.lu> ( the private
> urls) .
>
> The issue that we have :
> --> The client that integrates saml has a tomcat and integrates a
> keycloak-saml.xml file. Of course, in this file the configuration is
> refering to security1.lu<http://security1.lu> ( the private address as
> the keycloak node only knows its private address).
> --> If we arrive during the load-balancing on the security1.lu<
> http://security1.lu> node, it will work. If I arrive on the second
> security2.lu<http://security2.lu> node, it will fail. When I dig a little
> bit more, it's because in fact, the SAMLRequest that is generated looks
> like this :
>
> <samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
> Destination="http://security1.lu<http://security1.lu>:8080/realms/xxx/protocol/saml"
> ForceAuthn="false" ID="ID_e563f50b-4ed8-454c-b938-0727d18ec08e"
> IsPassive="false" IssueInstant="2016-10-11T12:52:09.865Z"
> Version="2.0"><saml:Issuer xmlns:saml="urn:oasis:names:
> tc:SAML:2.0:assertion">xxxxx</saml:Issuer><samlp:NameIDPolicy
> AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:
> persistent"></samlp:NameIDPolicy></samlp:AuthnRequest>
>
> The error that I get is an invalid_destination because we receive this
> SAMLRequest on the security2.lu<http://security2.lu> node :
>
> 2016-10-11 14:52:10,152 WARN  [org.keycloak.events] (default task-2)
> type=LOGIN_ERROR, realmId=xxx, clientId=null, userId=null, ipAddress=xxxx,
> error=invalid_authn_request, reason=invalid_destination
>
> >From what I see there is for saml client, a Clustering tab where I have
> currently nothing. Maybe I need to add some host nodes here ? But i don't
> know how to proceed.
>
> Or is there any way to define both security1.lu<http://security1.lu> and
> security2.lu on the Saml XML configuration that the client integrates?
>
> We have set proxy-address-forwarding=true
>
> Thank you for your help.
>
> Kr,
>
>
>
>
>
>
>   Br
>
> Dimitrios Gkazgkas
> IT Solutions Architect
>
>
>
> ________________________________
>
> **** DISCLAIMER ****
> http://www.tango.lu/maildisclaimer
> _______________________________________________
> keycloak-user mailing list
> keycloak-user at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/keycloak-user
>
>
>
>
>
>
>
>
>
>
>


More information about the keycloak-user mailing list