3

I'm trying to provide authentication of one of my pages on my Jetty server. I'm doing it all programatically, so there's no xml involved.

I've found I can protect particular contexts by using the ConstraintSecurityHandler. While this works fine for Servlets I'm running, I've tried to extend it to work for the ResourceHandler as well, and I've ran into problems. The code I am trying is found below.

If I place the ResourceHandler block first, then the authentication fails to pop up. If I place the ResourceHandler block after the SecurityHandler block, then the authentication pops up, but after authentication, the ResourceHandler page (/resources) does not appear, and Jetty gives me a 404.

Is there any way I can password protect the page hosted by the ResourceHandler programatically??

final static String REALM = "REALM";

.
.
.

public static void main(String[] args){   
.
.
.
    ResourceHandler resourceHandler = new ResourceHandler(); //set up resourceHandler to host directory of files at /resources
    resourceHandler.setDirectoriesListed(true);
    resourceHandler.setResourceBase("." + File.separator + "files");
    ContextHandler resourceContextHandler = new ContextHandler();
    resourceContextHandler.setContextPath("/resources");
    resourceContextHandler.setHandler(resourceHandler);
    handlers.addHandler(resourceContextHandler);
.
.
.
    ConstraintSecurityHandler csh = getConstraintSecurityHandler();
    ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
    servletContextHandler.setSecurityHandler(csh);
    handlers.addHandler(servletContextHandler);
.
.
.

    server.setHandler(handlers);
    server.start();
    server.join();
}

private ConstraintSecurityHandler getConstraintSecurityHandler(){
    Constraint constraint = new Constraint(Constraint.__BASIC_AUTH, "user");
    constraint.setRoles(new String[]{"user","admin"});
    constraint.setAuthenticate(true);

    ConstraintMapping statsConstraintMapping = new ConstraintMapping();
    statsConstraintMapping.setConstraint(constraint);
    statsConstraintMapping.setPathSpec("/resources"); //directory I want to protect

    ConstraintSecurityHandler csh = new ConstraintSecurityHandler();
    csh.setAuthenticator(new BasicAuthenticator());
    csh.setRealmName(REALM);
    csh.setConstraintMappings(new ConstraintMapping[] {statsConstraintMapping});

    csh.setLoginService(getHashLoginService());

    return csh;
}

private HashLoginService getHashLoginService() {
    HashLoginService loginServ = new HashLoginService();
    loginServ.setName(REALM);
    loginServ.setConfig("realm.properties"); //location of authentication file
    loginServ.setRefreshInterval(1);
    return loginServ;
}
Joe Leo
  • 400
  • 5
  • 12
user1455951
  • 41
  • 1
  • 3

1 Answers1

4

The security handler goes in front of the resource handler so in the chain of processing the security handler is consulted first.

See:

https://github.com/eclipse/jetty.project/blob/master/examples/embedded/src/main/java/org/eclipse/jetty/embedded/SecuredHelloHandler.java

Joe Leo
  • 400
  • 5
  • 12
jesse mcconnell
  • 7,102
  • 1
  • 22
  • 33
  • For clarification, the security handler must point to the webapp handler, so it secures the webapp. I had a list of handlers (ContextHandlerCollection) and just added the security handler to this list - that didn't work. – davidfrancis Jun 17 '15 at 10:24
  • Can you also tell how this is doable using jetty.xml file? – Sohan Dec 24 '15 at 09:31