Search code examples
javafilterspnego

SPNEGO - Exclude specific URL / URL pattern from authentication check


I implemented Single Sign On into my application. Now I got URL's which I dont want to use with single sign on (for example an unprotected webservice). How I can I do that? Is there an SPNEGO init param, which is supported?

<display-name>myapp</display-name>
<welcome-file-list>
    <welcome-file>/faces/index.xhtml</welcome-file>
</welcome-file-list>
<error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/faces/error.xhtml</location>
</error-page>
<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>prototype</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

Now I would like to configure something like this:

<filter>
    <filter-name>SpnegoHttpFilter</filter-name>
    <filter-class>net.sourceforge.spnego.SpnegoHttpFilter</filter-class>
[...]
  <init-param>
   <param-name>excludePattern</param-name>
   <param-value>.*rest.*</param-value>
  </init-param>
</filter>

Edited: 09/11/2018 01:35 PM

In the SPNEGO sources, in class SpnegoHttpFilter.java I found what I was looking for (including the comment):

   @Override
public void doFilter(final ServletRequest request, final ServletResponse response
    , final FilterChain chain) throws IOException, ServletException {

    final HttpServletRequest httpRequest = (HttpServletRequest) request;
    final SpnegoHttpServletResponse spnegoResponse = new SpnegoHttpServletResponse(
            (HttpServletResponse) response);

    // skip authentication if resource is in the list of directories to exclude
    if (exclude(httpRequest.getContextPath(), httpRequest.getServletPath())) {
        chain.doFilter(request, response);
        return;
    }

But now my question is, how does this function retrieve a list of directories to skip authentication?


Solution

  • After researching a while, including browsing through docussion forums on sourceforge, I was not able to make the SPNEGO skip-authentication-mechanism running. There seems to be no example configuration. I opened a question SPNEGO sourceforce page, but for now I implemented a Workaround.

    I took the last build of spnego. (build r9, downloaded here).

    In class SpnegoHttpFilter I created an global variable, called "excludePattern".

    private String excludePattern = null;
    

    In my web.xml of my web application, I created a new init param as following:

    <init-param> 
     <param-name>excludePattern</param-name> 
     <param-value>.*rest.*</param-value>
    </init-param> 
    

    In class SpnegoHttpFilter I need to read the param of web.xml like this:

    this.excludePattern = filterConfig.getInitParameter("excludePattern");
    

    Afterwords, in class SpnegoHttpFilter I go to the function doFilter() and insert following:

    String url = httpRequest.getRequestURL().toString();
    if (Pattern.matches(this.excludePattern, url)) {
       chain.doFilter(request, response);
       LOGGER.fine("Excluded URL requested");
       return;
    }
    

    Now, the code checks the given pattern against the requested URL. If pattern is part of the URL, authentication will be skipped.

    I hope I make the original solution, made by spnego developpers, working soon. As Long as I don't, I go with this workaround.