如何禁用特定servlet / pathSpec的身份验证?

时间:2018-09-21 18:05:25

标签: java servlets jetty forms-authentication jetty-9

我的代码如下(引用为Embedded Jetty - Programatically add form based authentication):

    ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS | ServletContextHandler.SECURITY);

    context.addServlet(new ServletHolder(new DefaultServlet() {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.getWriter().append("Hello " + request.getUserPrincipal().getName());
        }
    }), "/*");

    context.addServlet(new ServletHolder(new DefaultServlet() {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.getWriter().append("<html><form method='POST' action='/j_security_check'>"
                    + "<input type='text' name='j_username'/>"
                    + "<input type='password' name='j_password'/>"
                    + "<input type='submit' value='Login'/></form></html>");
        }
    }), "/login");

    context.addServlet(new ServletHolder(new DefaultServlet(){
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.getWriter().append("This is the metrics page!");
        }
    }), "/metrics");

    Constraint constraint = new Constraint();
    constraint.setName(Constraint.__FORM_AUTH);
    constraint.setRoles(new String[]{"admin"});
    constraint.setAuthenticate(true);

    ConstraintMapping constraintMapping = new ConstraintMapping();
    constraintMapping.setConstraint(constraint);
    constraintMapping.setPathSpec("/*");

    ConstraintSecurityHandler securityHandler = new ConstraintSecurityHandler();
    securityHandler.addConstraintMapping(constraintMapping);
    TestingLoginService loginService = new TestingLoginService();
    securityHandler.setLoginService(loginService);

    FormAuthenticator authenticator = new FormAuthenticator("/login", "/login", false);
    securityHandler.setAuthenticator(authenticator);

    context.setSecurityHandler(securityHandler);

这可行,但是我希望/ metrics servlet不需要对用户进行身份验证。但是,我仍然希望所有其他路径都进入登录名和“ Hello” servlet。

我能想到的唯一其他解决方案是将“ Hello” servlet移至其他路径,并使根路径仅重定向至该路径。这样,我可以将ConstraintMapping的pathSpec设置为也不包含/ metrics路径的内容。

1 个答案:

答案 0 :(得分:0)

ConstraintMapping constraintMapping = new ConstraintMapping();
constraintMapping.setConstraint(constraint);
constraintMapping.setPathSpec("/*");

不幸的是,服务器约束映射没有“排除”的概念。

您必须添加多个满足您需要的路径规范,而不必在该路径规范列表中包括/metrics路径规范。