我正在使用嵌入式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类开始处理请求之前,是否可以在一开始就运行安全检查?谢谢。
答案 0 :(得分:0)
正如@Paul Samsotha所建议的,ContainerRequestFilter
是一个不错的选择。