Java 在OSGi中为servlet配置身份验证

Java 在OSGi中为servlet配置身份验证,java,servlets,osgi,karaf,pax-web,Java,Servlets,Osgi,Karaf,Pax Web,我有Karaf3.0.2作为我的容器,它使用PaxWeb(我认为它再次使用jetty)。我有几个servlet,我在某个别名下注册为OSGi服务 默认情况下,etc/jetty.xml的配置使我可以使用JAASLoginService,这也是我希望使用的服务 问题是,我想同时使用基本身份验证和表单身份验证: 与/ui/*匹配的所有内容都应使用表单身份验证 匹配/rest/*的所有内容都应使用基本身份验证 我尝试了很多,但我甚至没有找到一个可以开始的点。我认为可以配置每个servlet,但我希

我有Karaf3.0.2作为我的容器,它使用PaxWeb(我认为它再次使用jetty)。我有几个servlet,我在某个别名下注册为OSGi服务

默认情况下,etc/jetty.xml的配置使我可以使用JAASLoginService,这也是我希望使用的服务

问题是,我想同时使用基本身份验证和表单身份验证:

  • 与/ui/*匹配的所有内容都应使用表单身份验证
  • 匹配/rest/*的所有内容都应使用基本身份验证
我尝试了很多,但我甚至没有找到一个可以开始的点。我认为可以配置每个servlet,但我希望全局配置


有什么想法吗?

你在这里确实有点与众不同。 如果您使用WebApplicationBundle(WAB)部署servlet,那么您拥有Web应用程序的所有常规元素。包括基本身份验证或基于表单的身份验证

public class AuthHttpContext implements HttpContext {

    public boolean handleSecurity(HttpServletRequest req,
        HttpServletResponse res) throws IOException {

        if (req.getHeader("Authorization") == null) {
            res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
        if (authenticated(req)) {
            return true;
        } else {
            res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }

    }

    protected boolean authenticated(HttpServletRequest request) {
        request.setAttribute(AUTHENTICATION_TYPE, HttpServletRequest.BASIC_AUTH);

        String authzHeader = request.getHeader("Authorization");
        String usernameAndPassword = new String(Base64.decodeBase64(authzHeader.substring(6).getBytes()));

        int userNameIndex = usernameAndPassword.indexOf(":");
        String username = usernameAndPassword.substring(0, userNameIndex);
        String password = usernameAndPassword.substring(userNameIndex + 1);

        // Here I will do lame hard coded credential check. HIGHLY NOT RECOMMENDED! 
        boolean success = ((username.equals("admin") && password
            .equals("admin")));
        if (success)
            request.setAttribute(REMOTE_USER, "admin");
        return success;
        }

...
}
因为您使用的是OSGi注册servlet的方式,所以您只能通过HttpContext来实现这一点。下面的示例取自,它使用基本身份验证

public class AuthHttpContext implements HttpContext {

    public boolean handleSecurity(HttpServletRequest req,
        HttpServletResponse res) throws IOException {

        if (req.getHeader("Authorization") == null) {
            res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
        if (authenticated(req)) {
            return true;
        } else {
            res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }

    }

    protected boolean authenticated(HttpServletRequest request) {
        request.setAttribute(AUTHENTICATION_TYPE, HttpServletRequest.BASIC_AUTH);

        String authzHeader = request.getHeader("Authorization");
        String usernameAndPassword = new String(Base64.decodeBase64(authzHeader.substring(6).getBytes()));

        int userNameIndex = usernameAndPassword.indexOf(":");
        String username = usernameAndPassword.substring(0, userNameIndex);
        String password = usernameAndPassword.substring(userNameIndex + 1);

        // Here I will do lame hard coded credential check. HIGHLY NOT RECOMMENDED! 
        boolean success = ((username.equals("admin") && password
            .equals("admin")));
        if (success)
            request.setAttribute(REMOTE_USER, "admin");
        return success;
        }

...
}
对于基于表单的,您需要一个额外的HttpContext。对于需要确保注册正确的HttpContext的每个匹配路径,也可以在下面的位置找到以下代码


我试过了,但在/status with auth中,它只显示了由自定义上下文修改的属性的值。没有登录对话框。相应的集成测试会对此进行测试,并且仍然有效。但它只是用auth测试/status的实际内容,甚至不执行登录-这就是我想要的。我希望每个访问servlet的人都必须通过基本或表单身份验证对自己进行身份验证。。。我会尽快修好的