[keycloak-user] Basic authentication - adapter not using backend-url for HttpPost?

Guy Davis guydavis.ca at gmail.com
Mon Jan 4 15:49:35 EST 2016


Good day,

I'm working with Keycloak 1.7.0.Final (in it's own Wildfly) behind a
HAProxy instance.  A REST service is deployed (as .war) on another server
(also behind HAProxy) in a JBoss EAP instance, protected using the Keycloak
adapter.

The deployment is protected as follows in standalone.xml of the JBoss
instance:

          <secure-deployment name="mytest.war">
                <realm>MyRealm</realm>
                <resource>my-resource</resource>

<use-resource-role-mappings>true</use-resource-role-mappings>
                <enable-basic-auth>true</enable-basic-auth>
                <public-client>true</public-client>
                <realm-public-key>MIIB...QAB</realm-public-key>
                <auth-server-url>/auth</auth-server-url>
                <auth-server-url-for-backend-requests>http://proxy:8080/auth
</auth-server-url-for-backend-requests>
                <ssl-required>NONE</ssl-required>

<principal-attribute>preferred_username</principal-attribute>
            </secure-deployment>

Here is relevant section of mytest.war's web.xml:

 <security-constraint>
    <web-resource-collection>
      <web-resource-name>All Admin</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>my-admins</role-name>
    </auth-constraint>
    <user-data-constraint>
      <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
  </security-constraint>

  <login-config>
    <auth-method>KEYCLOAK</auth-method>
    <realm-name>this is ignored currently</realm-name>
  </login-config>
  <security-role>
    <description>Admin access for admins.</description>
    <role-name>my-admins</role-name>
  </security-role>

Due to the use of the old JBoss EAP 6.1 server, I've had to add the
following to mytest.war's jboss-web.xml to support proxying, with proxy
headers added by HAProxy:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
  <security-domain>keycloak-web</security-domain>
  <context-root>mytest</context-root>
  <valve>
    <class-name>org.apache.catalina.valves.RemoteIpValve</class-name>
    <param>
      <param-name>protocolHeader</param-name>
      <param-value>x-forwarded-proto</param-value>
    </param>
  </valve>
</jboss-web>

The hostname "proxy" is resolvable within the cluster behind HAProxy and
will result in direct access to the Keycloak instance.   From outside the
cluster, all the services are mapped to the same HTTP namespace by
HAProxy.  So an external request to http://[external_haproxy]/auth will be
proxied to Keycloak in the cluster. The 'my-resource' Keycloak client has
direct access grants enabled and is set to Public access.

In testing, where the entire cluster is launched in Vagrant running on
Windows, if I access http://localhost/mytest/api/... in a browser, I am
shown the Keycloak login and get the REST service result as expected.  This
tells me that the majority of my configuration above is good.

However, if I use a client like curl or JMeter to send a similar HTTP
request with the Basic authentication header added:
    Authorization: Basic YWRtaW46YWRtaW4=

Then the following is observed in the JBoss log from Keycloak adapter:

  2016-01-04 20:03:49,295 DEBUG
[org.keycloak.adapters.BasicAuthRequestAuthenticator] (http-/0.0.0.0:8080-1)
Failed to obtain token: java.net.ConnectException: Connection refused

Upon debugging through the Keycloak adapter code to watch the basic
authentication process, I found myself
in BasicAuthRequestAuthenticator,getToken() where I find that
*deployment.getAuthServerBaseUrl()*  == "http://localhost/auth" which is
not valid on the JBoss EAP system.  This tells me that the external
hostname (Vagrant host) is being used to build the URI for contacting the
internal Keycloak host.  In particular, the provided value for
<auth-server-url-for-backend-requests> is not being used.  Since this Basic
Auth code uses this URI to issue a "backend" request, I would have expected
the <auth-server-url-for-backend-requests> value to be used.

So my question is whether I am missing a basic authentication specific
configuration step or whether I've encountered a defect in URI handling for
basic auth + backend requests. Interestingly, in the attached Eclipse
screenshot, the deployment object is aware of the http://proxy:8080 URI
backend but it is not being used for authServerBaseUrl.

Note, the scope of this problem is more than my Vagrant/localhost example.
I expect the same problem to manifest in our AWS test environment where
external hostnames don't resolve for cluster members identified by internal
hostnames only.  I'm hoping to find a solution before this hits our test
environment.

Thanks in advance,
Guy
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/keycloak-user/attachments/20160104/96c61231/attachment-0001.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 2016-01-04_134423.png
Type: image/png
Size: 32320 bytes
Desc: not available
Url : http://lists.jboss.org/pipermail/keycloak-user/attachments/20160104/96c61231/attachment-0001.png 


More information about the keycloak-user mailing list