How to get javax.servlet.Filter called before Keyc

2019-04-21 06:24发布

问题:

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>

回答1:

Have you tried to change the order of the elements in the web.xml (eg put filter definitions BEFORE servlet definitions) ?

Not sure it will works, but the doc says: "The order of the filters in the chain is the same as the order that filter mappings appear in the web application deployment descriptor"

The principle may be also true for the order between servlets and filters...



回答2:

It may be because Tomcat Authentication Valve kick in before Filters. Check Authenticators.properties file. You may need to wrap your filter class as Valve