嵌入式码头:如何在HTTP请求到达后立即运行安全处理程序?

时间:2018-09-03 23:11:33

标签: jersey jetty embedded-jetty

我正在使用嵌入式Jetty和Jersey。我的问题是:是否有可能使SecurityHandler的码头在HTTP请求到达Jersey类之前生效?

这是我的代码:(很抱歉,可能太多了。) 码头服务器初始化的类:

public class JettyHttpComponent extends AbstractLifeCycleComponent {

    private static final String REST_SOURCE_KEY = "jersey.config.server.provider.classnames";

    //TODO Security config and implementation
    public int start() throws RuntimeException {

        Server jettyServer = new Server(8080);
        ServletContextHandler context = new ServletContextHandler(jettyServer, "/", ServletContextHandler.SESSIONS|ServletContextHandler.SECURITY);
        context.setContextPath("/");
        context.setSecurityHandler(basicAuth());


        ServletHolder jerseyServlet = context.addServlet(
             org.glassfish.jersey.servlet.ServletContainer.class, "/*");
        jerseyServlet.setInitOrder(0);

        //load rest resources
        jerseyServlet.setInitParameter(REST_SOURCE_KEY, IndexService.class.getCanonicalName());


        try {
            jettyServer.start();
            jettyServer.join();
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            jettyServer.destroy();
        }
        return 0;
    }

    public int stop() throws RuntimeException {
        //close resources
        try {
            close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        System.out.println("Server stopped.");
        return 0;
    }

    private SecurityHandler basicAuth() {
        ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();
        LoginService loginService = new LDAPLoginService();
        securityHandler.setLoginService(loginService);  
        return securityHandler;
    }

}

LDAPLoginService中的basicAuth()类是我的自定义登录类,扩展了AbstractLoginService

Jersey类处理http请求:

@Path("/index")
public class IndexService extends BaseRestService {

    @PUT
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response index(@Context SecurityContext securityContext,
            @Context HttpHeaders headers,
            @Context HttpServletRequest httpRequest,
            @QueryParam("algorithm") String algorithm,
            @QueryParam("executionMode") String mode,
            String request) {
        long t1 = System.currentTimeMillis();
        String response = null;
        IndexContext context = null;
        try {
            init();
            //setup context with security, headers, options and request
            ServiceUserContext suc = buildServiceUserContext(securityContext, httpRequest);
            if (suc == null) {
                return Response.status(Status.UNAUTHORIZED).entity(response).build();
            }
            ServiceDataContext sdc = buildServiceDataContext(request);
            context = IndexContext.builder().algorithm(algorithm).serviceDataContext(sdc).
                    serviceUserContext(suc).build();
            //dispatch service to entity matching core services
            dispatch(context);
        } catch(Throwable t) {
            handlerErrors(t, context);
        } finally {
            if (context != null) {
                close(context);
                response = context.getServiceDataContext().getResponse();
                System.out.println("Index takes: " + (System.currentTimeMillis() - t1) + " ms");
            }
        }
        return Response.status(Status.OK).entity(response).build();
    }   
}

在方法buildServiceDataContext()中,我调用了securityContext.getUserPrincipal(),并且扩展了LDAPLoginService的{​​{1}}类在达到AbstractLoginService之前没有任何作用。甚至在Jersey类开始处理请求之前,是否可以在一开始就运行安全检查?谢谢。

1 个答案:

答案 0 :(得分:0)

正如@Paul Samsotha所建议的,ContainerRequestFilter是一个不错的选择。