【问题标题】:Dropwizard View authentication by exampleDropwizard 查看认证示例
【发布时间】:2016-02-14 07:08:23
【问题描述】:

我熟悉在 Dropwizard 中实现 BasicAuth 安全性,但仅适用于 RESTful 端点/资源。

我现在正在尝试使用 Dropwizard Views,看看我是否可以将它同时用作 Web 和 REST 服务器。 Web 应用程序将具有“公共”页面(实际上只是静态 HTML 文件;“关于我们”、“联系我们”等)以及真正构成应用程序的“私有”(动态)页面。要访问这些页面,用户必须经过身份验证(登录)。

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

  • 一种典型的DW认证REST API客户端的安全机制,我比较熟悉;和
  • 一种实现登录系统的方法,用于对 Web 应用页面/资源的最终用户进行身份验证

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


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

  1. 用户尝试访问“经过身份验证的”(私有)URL。
  2. 一个 servlet 过滤器(我自己创建并使用 environment 注册)拦截请求并可以判断(可能是 cookie/会话变量?)用户是否经过身份验证。
  3. 如果用户通过身份验证,则允许他们继续访问其预期的 URL(“目标 URL”)。否则,它们将被重定向到登录页面。当他们登录 DW 资源/控制器时,会将他们的凭据交给 Shiro,然后由 Shiro 决定凭据是否有效。
  4. 如果凭据有效,它们会获得一个 cookie/会话变量 (?) 并被重定向到其目标 URL。否则,它们将被重定向回登录页面,现在将显示失败消息。

我主要担心的是: * 我应该为 servlet 检查的 cookie/session var 实现什么?;和 * 如何将我的身份验证控制器(即处理登录页面和目标 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'?
    }
}

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

【问题讨论】:

    标签: java authentication cookies shiro dropwizard


    【解决方案1】:

    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 会话。

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

    【讨论】:

    • 非常感谢 @silb (+1) - 如果您不介意,只需为您提供一些快速跟进(关于 servlet 会话):(1)确认this method 是从 DW 应用程序内部“启用会话管理器”的正确方法? (2) 唯一让我担心为视图(网页)启用会话的是它可能会弄乱我的 REST 端点,因为 REST 应该是无状态的。想法?再次感谢!
    • NM 对于上面的#1,我在 Dropwizard-Shiro README 中看到了关于启用会话的注释。仍然轻微地关注#2...
    猜你喜欢
    • 1970-01-01
    • 2015-01-04
    • 2015-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    相关资源
    最近更新 更多