2

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

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

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

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

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

有任何想法吗?

4

1 回答 1

2

你必须在这里有所区别。如果您使用 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());
        }
    }
...
}
于 2014-10-27T21:18:04.120 回答