javashirojetty-9

UnavailableSecurityManagerException while integrating shiro with jetty


I'm trying to integrate Shiro with our "legacy" Client/Server application (Java 8, Jetty 9, Shiro 1.9). I followed the Documentation on https://shiro.apache.org/web.html and tried to adapt it to our existing code, but I get an UnavailableSecurityManagerException when I try to access the SecurityManager.

I set up a ServletContextHandler and tried to combine it with our existing request handler (AbstractHandler). The funny thing is, I can access the context with the Security Manager instance (i.e., with request.getServletContext().getAttribute("org.apache.shiro.web.env.EnvironmentLoader.ENVIRONMENT_ATTRIBUTE_KEY")), but it doesn't get handled by shiro.

I could set the security manager manually with SecurityUtils, but that's not what I want as I want request based security. Also, the session cookies are not set and processed at all.

Here's a (stripped down) version of my code:

/* Context */

public class SecurityContext extends ServletContextHandler {
    SecurityContext(String configLocations) {
        super();
        EnvironmentLoaderListener listener = new EnvironmentLoaderListener();
        //this.setInitParameter("shiroEnvironmentClass", "org.apache.shiro.web.env.IniWebEnvironment");
        this.addFilter("org.apache.shiro.web.servlet.ShiroFilter", "/*", EnumSet.allOf(DispatcherType.class));
        this.setInitParameter("shiroConfigLocations", configLocations);
        this.addEventListener(listener);
    }
}
/* Request Handler */

public final class RequestHandler extends AbstractHandler {
    public void handle(final String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException {
        Subject subject = SecurityUtils.getSubject(); // throws UnavailableSecurityManagerException!
        HandlerResult handlerResult = JsonResult.notFound(this.gson);
        // ...
        handlerResult.writeTo(response);
        baseRequest.setHandled(true);
    }
}

/* Web Server: */

protected void startUp() throws Exception {
        SslContextFactory sslContextFactory = new SslContextFactory();
        sslContextFactory.setKeyStore(SSLKeyStore.create("server.keystore"));
        sslContextFactory.setKeyStorePassword(SSLKeyStore.KEYSTORE_PASSWORD);
        sslContextFactory.setProtocol("TLSv1.2");

        SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, "http/1.1");
        HttpConnectionFactory http = new HttpConnectionFactory(new HttpConfiguration());


        /* connectors */
        ServerConnector sslConnector = new ServerConnector(this.server, ssl, http);
        sslConnector.setPort(this.port);
        this.server.addConnector(sslConnector);

        /* handlers */
        GzipHandler gzip = new GzipHandler();
        gzip.setIncludedMimeTypes("text/html", "text/plain", "application/json");

        RequestHandler requestHandler = new RequestHandler();

        SecurityContext context = new SecurityContext("classpath:shiro.ini");
        context.setGzipHandler(gzip);
        context.insertHandler(new HandlerWrapper() {
            @Override
            public void handle(final String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException {
                SecurityUtils.getSubject(); // throws UnavailableSecurityManagerException!
                requestHandler.handle(target, baseRequest, request, response);
            }
        });

        server.setHandler(context);

        this.server.start();
    }


Solution

  • I've found out that ShiroFilter didn't get triggered on requests. I changed my request handler to extend javax.servlet.http.HttpServlet, now it's working!