为嵌入式 Jetty 12 添加安全性

问题描述 投票:0回答:1

我正在尝试为嵌入式 Jetty 12 服务器添加安全性。

什么有效:

  • 我可以冲浪到/,并且无需身份验证即可获得我的登陆页面
  • 我可以冲浪到 /web,它会获取正确的网页,并建立 websocket 连接,两者都无需身份验证
  • 如果我浏览到 /model,它会分派到我的登录页面
  • 如果我输入了错误的凭据,它会返回到我的登录页面

什么不起作用:

  • 如果我输入了正确的凭据,它就会进入我的/主登陆页面;我希望它继续到 /model
  • 如果我随后浏览到 /model,它仍然显示我的登录页面。我永远无法到达/model

这是我的代码:

    public WebsocketServer(int port, Model model, SessionManager sessionManager) throws Exception {
        server_ = new Server(port);
        server_.setRequestLog(new CustomRequestLog(new Slf4jRequestLogWriter(), CustomRequestLog.EXTENDED_NCSA_FORMAT));


        SessionHandler sessionHandler = new SessionHandler();
        server_.setHandler(sessionHandler);


        ConstraintSecurityHandler security = new ConstraintSecurityHandler();
        sessionHandler.setHandler(security);

        HashLoginService loginService = new HashLoginService("login");
        try (ResourceFactory.Closeable rf = ResourceFactory.closeable()) {
            Path pw = Paths.get("cfg/web.passwords");
            log_.info("Configuring login passwords from {} {}", pw, pw.toFile().exists());
            Resource r = rf.newResource(pw);
            loginService.setConfig(r);
            security.setLoginService(loginService);
        }
        FormAuthenticator formAuthenticator = new FormAuthenticator("/login", "/login", true);
        //formAuthenticator.setAlwaysSaveUri(true);
        security.setAuthenticator(formAuthenticator);


        ConstraintMapping cm = new ConstraintMapping();
        cm.setPathSpec("/model/*");
        cm.setConstraint(Constraint.from("admin"));
        security.setConstraintMappings(Collections.singletonList(cm));


        ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
        security.setHandler(contextHandlerCollection);


        // add a context for /model
        ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS | ServletContextHandler.SECURITY);
        servletContextHandler.setContextPath("/model");

        servletContextHandler.addServlet(new ServletHolder(new ModelServlet(model)), "/*");
        contextHandlerCollection.addHandler(servletContextHandler);


        // add a context for /web
        servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS | ServletContextHandler.SECURITY);
        servletContextHandler.setContextPath("/web");
        servletContextHandler.setWelcomeFiles(new String[]{"websocket.html"});

        Resource webResource = ResourceFactory.of(servletContextHandler).newResource(Paths.get("cfg/web"));
        if (!Resources.isReadableDirectory(webResource))
            throw new FileNotFoundException("Unable to find web resource");

        ServletHolder holderWeb = new ServletHolder("web", DefaultServlet.class);
        holderWeb.setInitParameter("baseResource", webResource.getURI().toASCIIString());
        holderWeb.setInitParameter("dirAllowed", "false");
        holderWeb.setInitParameter("pathInfoOnly", "true");
        servletContextHandler.addServlet(holderWeb, "/*");

        // allow websocket upgrades in this context
        JettyWebSocketServletContainerInitializer.configure(servletContextHandler, (context, configurator) ->
        {
            configurator.setIdleTimeout(Duration.ofMillis(30000));
            configurator.addMapping("/ws", (req, res) -> {
                Session s = new Session(req);
                sessionManager.add(s);
                return s;
            });
        });
        contextHandlerCollection.addHandler(servletContextHandler);


        // add a context for the login page
        servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS | ServletContextHandler.SECURITY);
        servletContextHandler.setContextPath("/login");
        servletContextHandler.addServlet(new ServletHolder(new FormAuthServlet()), "/*");
        contextHandlerCollection.addHandler(servletContextHandler);


        // add a context for the root
        servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        servletContextHandler.setContextPath("/");
        Resource baseResource = ResourceFactory.of(servletContextHandler).newResource(Paths.get("cfg/web"));
        if (!Resources.isReadableDirectory(baseResource))
            throw new FileNotFoundException("Unable to find base resource");
        servletContextHandler.setBaseResource(baseResource);
        ServletHolder servletHolder = new ServletHolder("root", DefaultServlet.class);
        servletContextHandler.addServlet(servletHolder, "/*");
        contextHandlerCollection.addHandler(servletContextHandler);


        server_.start();
        //server.join();
    }

(顺便说一句,我不知道我是否正确链接了 Session、Security 和 ContextHandler)

jetty embedded-jetty jetty-12
1个回答
0
投票

事实证明,我的登录表单的操作是“j_security_check”而不是“/j_security_check”。当我使用正确的操作时,一切都会正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.