How to integrate waffle NegotiateSecurityFilter spring-security with sparkjava embedded jetty?

649 views Asked by At

Our application is using sparkjava http://sparkjava.com/ as the REST framework. The jetty server is embedded in the application (sparkjava default). We are also using spring for dependency injection.

For providing AD authentication, we need to integrate the waffle's NegotiateSecurityFilter.

As per waffle documentation and several online resources including stackoverflow, a DelegatingFilterProxy is required with the name springSecurityFilterChain.

But since we are not using spring MVC, I have to add it as follows:

    ServletContextHandler sparkContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
    sparkContext.addFilter(new FilterHolder( new DelegatingFilterProxy( "springSecurityFilterChain" ) ),"/*", EnumSet.allOf( DispatcherType.class ));

And since a ContextLoaderListener does not already exist, need to add in the following manner:

    sparkContext.addEventListener( new ContextLoaderListener() );

But it gives the error "Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader" at time of server startup.

Please let me know a solution in this scenario if you have successfully integrated spring-security DelegatingFilterProxy with embedded jetty and sparkjava (without using spring MVC).

1

There are 1 answers

0
VJB On

This is how I achieved it finally:

In the main method where I have access to the sparkContext:

ServletContextHandler sparkContext = new  ServletContextHandler(ServletContextHandler.SESSIONS);
sparkContext.setContextPath("/");
sparkContext.addServlet(DefaultServlet.class, "/*");

addSPNEGOFilter(sparkContext);

And the implementing methods are as:

private void addSPNEGOFilter(ServletContextHandler sparkContext) {
    final ServletHandler handler = new ServletHandler();
    final FilterHolder fh = handler.addFilterWithMapping(NegotiateSecurityFilter.class, <SPNEGO_FILTER_PATH>,
            EnumSet.allOf(DispatcherType.class));
    setNegotiateFilterParams(fh);
    sparkContext.addFilter(fh, <SPNEGO_FILTER_PATH>, EnumSet.allOf(DispatcherType.class));
}

Add the following properties to the holder:

private static void setNegotiateFilterParams(final FilterHolder fh) {
    fh.setInitParameter("principalFormat", "fqn");
    fh.setInitParameter("roleFormat", "both");

    fh.setInitParameter("allowGuestLogin", "false");
    fh.setInitParameter("impersonate", "false");

    fh.setInitParameter("securityFilterProviders",
            "waffle.servlet.spi.NegotiateSecurityFilterProvider");
    fh.setInitParameter("waffle.servlet.spi.NegotiateSecurityFilterProvider/protocols", "Negotiate");
}