Please it's working. We're planning on improving the documentation around
this as I think it's far from obvious at the moment.
On 27 October 2016 at 17:43, GKAZGKAS Dimitrios (TAN/MST) <
Dimitrios.Gkazgkas(a)tangoservices.lu> wrote:
Thank you STian.
Finally we make it work.
The real issue was that we had not configured our RP to preserve the
original Host Header (security.lu) and pass it on to the server on the
private network behind. This can be done if in RP (apache mod_proxy) you
have:
ProxyPreserveHost On
This specific configuration someone can find in EAP HA configuration
(load balance enable)
https://access.redhat.com/documentation/en/red-hat-
jboss-enterprise-application-platform/7.0/paged/
configuration-guide/chapter-21-configuring-high-
availability#mod_proxy-config
and thanks to Stian we got the hint to search for it and able to
understand if works or not
(check
http://security.lu/auth/realms/master/protocol/saml/descriptor)
but to be honest it was not clearly defined as prerequisite in the
keycloack cluster documentation guide.
Br
Dimitrios Gkazgkas
IT Solutions Architect
............................................................
..................................
*From:* Stian Thorgersen [mailto:sthorger@redhat.com]
*Sent:* 26 October 2016 15:06
*To:* GKAZGKAS Dimitrios (TAN/MST) <Dimitrios.Gkazgkas(a)tangoservices.lu>
*Cc:* keycloak-user(a)lists.jboss.org; Benoît Reny <benoit.reny(a)its4u.lu>;
PIOCEL Vincent (TAN/MST) <vincent.piocel(a)tangoservices.lu>
*Subject:* Re: [keycloak-user] SAML in a keycloak cluster
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(a)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@redhat.com]
*Sent:* 20 October 2016 13:20
*To:* GKAZGKAS Dimitrios (TAN/MST) <Dimitrios.Gkazgkas(a)tangoservices.lu>
*Cc:* keycloak-user(a)lists.jboss.org; Benoît Reny <benoit.reny(a)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(a)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@redhat.com]
*Sent:* 19 October 2016 16:12
*To:* GKAZGKAS Dimitrios (TAN/MST) <Dimitrios.Gkazgkas(a)tangoservices.lu>
*Cc:* keycloak-user(a)lists.jboss.org; Benoît Reny <benoit.reny(a)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(a)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@redhat.com]
*Sent:* 19 October 2016 14:36
*To:* GKAZGKAS Dimitrios (TAN/MST) <Dimitrios.Gkazgkas(a)tangoservices.lu>
*Cc:* keycloak-user(a)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(a)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@redhat.com <sthorger(a)redhat.com>]
*Sent:* 18 October 2016 20:12
*To:* GKAZGKAS Dimitrios (TAN/MST) <Dimitrios.Gkazgkas(a)tangoservices.lu>
*Cc:* keycloak-user(a)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(a)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@redhat.com]
*Sent:* 17 October 2016 20:41
*To:* GKAZGKAS Dimitrios (TAN/MST) <Dimitrios.Gkazgkas(a)tangoservices.lu>
*Cc:* keycloak-user(a)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(a)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(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-user