【问题标题】:Configure authentication for servlets in OSGi在 OSGi 中为 servlet 配置身份验证
【发布时间】:2014-12-22 22:36:35
【问题描述】:

我有 Karaf 3.0.2 作为我的容器,它使用 pax web(我认为它再次使用码头)。我有几个 servlet,我在某个别名下注册为 OSGi 服务。

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

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

  • 匹配 /ui/* 的所有内容都应使用表单身份验证
  • 与 /rest/* 匹配的所有内容都应使用基本身份验证

我尝试了很多,但我什至没有找到可以开始的点。我认为可以配置每个 servlet,但我想在全局范围内进行。

有什么想法吗?

【问题讨论】:

    标签: java servlets osgi karaf pax-web


    【解决方案1】:

    您确实在这里有所区别。 如果您使用 WebApplicationBundle (WAB) 来部署 Servlet,您将拥有 Web 应用程序的所有常规元素。包括基本或基于表单的身份验证。

    由于您使用的是 OSGi 注册 Servlet 的方式,因此您只能通过 HttpContext 来执行此操作。下面的示例取自Pax Web Samples,它使用基本身份验证。

    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 的每个匹配路径,也可以在 Pax Web Samples 找到以下代码。

    public final class Activator implements BundleActivator {
    
    ...
    
        public void start(BundleContext bc) throws Exception {
            httpServiceRef = bc.getServiceReference(HttpService.class);
            if (httpServiceRef != null) {
                httpService = (HttpService) bc.getService(httpServiceRef);
    
                ...
    
                httpService.registerServlet("/status-with-auth",
                    new StatusServlet(), null, new AuthHttpContext());
            }
        }
    ...
    }
    

    【讨论】:

    • 我试过了,但在 /status-with-auth 它只显示自定义上下文修改的属性值。没有登录对话框。
    • 相应的集成测试确实对此进行了测试,并且仍然有效。 github.com/ops4j/org.ops4j.pax.web/blob/master/pax-web-itest/…
    • 但它只是测试 /status-with-auth 的实际内容,甚至不执行登录 - 这就是我想要的。我希望每个访问 servlet 的人都必须通过基本身份验证或表单身份验证来验证自己。
    • 如果是这种情况,请在 Pax Web 上提交错误
    • 看起来你发现了一个错误......我会尽快修复它
    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    相关资源
    最近更新 更多