Dropwizard View 身份验证示例

Dropwizard View authentication by example

我熟悉在 Dropwizard 中实现 BasicAuth 安全性,但仅适用于 RESTful endpoints/resources.

我现在正在试验 Dropwizard Views,看看我是否可以将它用作 Web 和 REST 服务器的一体机。 Web 应用程序将有 "public" 页面(实际上只是静态 HTML 文件;"About Us"、"Contact Us" 等)以及 "private"(动态)真正构成应用程序的页面。要访问这些页面,用户必须经过身份验证(登录)。

所以这意味着我需要两种不同的 DW 身份验证机制:

理想情况下,我希望 Apache Shiro 为我的系统(REST 和 Web 类似)处理所有身份验证,并且我看到 Dropwizard-Shiro 库,但它似乎只对 REST 端点进行身份验证。


我的网络登录系统需要像这样工作:

  1. 用户试图进入 "authenticated"(私人)URL。
  2. 一个 servlet 过滤器(我自己创建并在 environment 上注册)拦截请求并可以告诉(也许 cookie/session var?)用户是否经过身份验证。
  3. 如果用户通过身份验证,他们将被允许继续他们的预期 URL(“目标 URL”)。否则,他们将被重定向到登录页面。当他们登录 DW 时 resource/controller 将他们的凭据交给 Shiro,Shiro 然后决定凭据是否有效。
  4. 如果凭据有效,他们将获得 cookie/session var (?) 并重定向到他们的目标 URL。否则,他们将被重定向回登录页面,该页面现在将显示一条失败消息。

我主要担心的是: * 我应该为 servlet 将检查的 cookie/session var 实现什么?;和 * 如何将我的 auth 控制器(即处理登录页面和目标 URL 之间重定向的资源)与 Shiro 集成? 是否可以通过那个 Dropwizard-Shiro 库?

迄今为止我最好的尝试:

自定义 Servlet 过滤器(已注册 environment):

public class AuthFilter implements ContainerResponseFilter {
    @Override
    public void filter(ContainerRequestContext requestContext, 
            ContainerResponseContext responseContext) {
        Cookie[] cookies = requestContext.getCookies();
        boolean authenticated = false;
        for(Cookie cookie : cookies) {
            // 1. This is my first concern. What is better/more secure
            //    than what I'm doing here?
            if("my_app_auth_cookie".equals(cookie.getName())) {
                authenticated = true;
            }
        }

        if(authenticated == false) {
            responseContext.sendDirect("/auth/login");
        }
    }
}

如果他们未通过身份验证,他们将重定向到 /auth/login,后者命中 AuthController(同样,作为资源注册到 environment):

@Path("/auth")
@Produces(MediaType.TEXT_HTML)
public class AuthController {
    @GET
    @Path("/login")
    public LoginPageView login() {
        // Render some "login.ftl" template as HTML.
    }

    @POST
    @Path("/authenticate")
    public ??? authenticate(??? username, ??? password) {
        // 2. Somehow send 'username' and 'password' to Shiro...
        MyAppUser user = myAppRealm.authenticate(username, password);

        // Now what do I do with 'user'?
    }
}

当用户在登录页面上提交表单时(可能是 POST 到 /auth/authenticate),我们以某种方式将他们输入的凭据交给 Shiro(我再次想使用它Dropwizard-Shiro lib,因为我可能也会将它用于我的 REST 端点)。

Apache Shiro 有自己的 filters 类型,在 shiro.ini.

中配置

示例:

[urls]
/api/** = noSessionCreation, authcBasic
/views/login = authc
/views/authenticated = authc, user

配置 authc 过滤器以重定向到您实现的登录表单页面。使用过滤器的 form parameters 和 POST 到 /views/login.

如果您在 Jetty 中启用会话管理器,Shiro 应该在他们从登录表单页面登录时创建 servlet 会话。

请注意,我还没有实际测试过这个配置。