Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get javax.servlet.Filter called before Keycloak Authentication

We have developed a REST API using the resteasy. (deployed in wildfly 10)

Basically these REST APIs are called internally from another application and end points are secured with keycloak.

But one endpoint is exposed to outside party (that endpoint is also secured with keycloak).

But since the outside party can't provide the Keycloak Autherization code, we have done an implementation where client is registerred with application generated auth_key and client will call the endpoint with that auth_key.

Then in the a web filter (a javax.servlet.Filter), using tha auth_key we get the relevant keycloak authntication Bearer token. If needed (eg : token expired) we call the Keycloak Server also. Once it is received we add that Autherization token to the httpRequest within the web filter and proceed to the end point application.

But the problem is, KeyCloak authentication is called before Web Filter. What I'm looking for is "how to get Web Filter called before keycloak authentication?"

EDIT :

Now I'm trying to find a way as mentioned in here. Setting Request Header to Request Before Authentication Happens in Keycloak. There I could get the call before authentication happens. But I'm unable to set the Request Header there.

web.xml

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    <display-name>Restful Web Application</display-name>
    <context-param>
        <param-name>resteasy.scan</param-name>
        <param-value>true</param-value>
    </context-param>

    <!-- keycloak -->

    <context-param>
        <param-name>keycloak.config.resolver</param-name>
        <param-value>package.to.HeaderBasedKeycloakConfigResolver</param-value>
    </context-param>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>REST endpoints</web-resource-name>
            <url-pattern>/ep-name/resource-name</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>resource-name</role-name>
        </auth-constraint>
    </security-constraint>

    <!-- more security-constraint -->
    <!-- more security-constraint -->
    <!-- more security-constraint -->

    <login-config>
        <auth-method>KEYCLOAK</auth-method>
        <realm-name>realm-name</realm-name>
    </login-config>

    <security-role>
        <role-name>role-name-for-resource-1</role-name>
        <role-name>role-name-for-resource-2</role-name>
        <!-- more security-role -->
        <!-- more security-role -->
        <!-- more security-role -->
    </security-role>

    <listener>
        <listener-class>
            org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
    </listener>

    <servlet>
        <servlet-name>resteasy-servlet</servlet-name>
        <servlet-class>
            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
        </servlet-class>
        <init-param>
            <param-name>resteasy.servlet.mapping.prefix</param-name>
            <param-value>/ep-name</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>resteasy-servlet</servlet-name>
        <url-pattern>/ep-name/*</url-pattern>
    </servlet-mapping>

    <filter>
      <filter-name>WebFilter</filter-name>
      <filter-class>package.to.filter.WebFilter</filter-class>
   </filter>

   <filter-mapping>
      <filter-name>WebFilter</filter-name>
      <url-pattern>/desired-ep-name/*</url-pattern>
   </filter-mapping>

</web-app>

enter image description here

like image 614
namalfernandolk Avatar asked Jul 17 '18 18:07

namalfernandolk


1 Answers

I know this is 2 years old, but I found a solutuon for this problem: Change your adapter to the servlet filter, mine was jboss/wildfly, and add to web.xml below your filter to change the request or response. In the case of jboss/wildfly, the authentication happens in a valve, so the authentication happens before any filters execute. Once you do this, you can control when keycloak does its work and put your filter before it.

web.xml

<filter>
        <filter-name>Keycloak Filter</filter-name>
        <filter-class>org.keycloak.adapters.servlet.KeycloakOIDCFilter</filter-class>
</filter>
    <filter-mapping>
        <filter-name>Keycloak Filter</filter-name>
        <url-pattern>/restricted/*</url-pattern>
        <url-pattern>/restricted/</url-pattern>
</filter-mapping>

Add appropriate version of keycloak-servlet-filter-adapter to your pom, and remove all the other security-constraints, auth-method, etc from web.xml.

like image 170
Jordan Walsh Avatar answered Oct 04 '22 01:10

Jordan Walsh