在Java Web应用程序中实现协作认证

时间:2016-08-14 17:58:17

标签: java authentication web-applications

我需要构建一个基于Java的Web应用程序,只有当该资源的所有授权用户都登录时,资源才可用。此外,如果任何授权用户注销,该资源将不再可用他们中的任何一个。

资源可以是任何类型(html页面,pdf文档,电子表格等)

是否有任何现有的认证标准/协议支持这种类型的要求,或者我是从头开始构建它?

2 个答案:

答案 0 :(得分:4)

  

仅当该资源的所有授权用户都已登录时,该资源才可用。此外,如果任何授权用户注销,该资源将不再可用于任何资源。

一旦您向用户授予了对资源的访问权限,该用户就可以下载/截取/保存/记录资源,无论它是PDF文档,图像还是音频文件。我不知道你想要建立什么的背景和目标,但是你应该知道它在任何情况下都是不安全的。

即使把这个考虑放在一边,你也需要一个实时的解决方案。一旦用户加载了包含资源的页面,您就需要能够隐藏或拒绝对他的修改权限。这意味着您必须在客户端使用WebSockets或Ajax Polling之类的东西,让前端知道您的服务器何时认为并非所有必需用户都在线,并且应该“拒绝”对资源的访问。但是再一次,因为这是客户端代码,它可以很容易地被更改或更改,它发送的请求很容易被用户阻止,因此它再次固有的不安全

我建议在这里给出一些上下文并描述你想要解决的问题是什么,因为很可能有一个更合理的解决方案来解决它。

如果不是所有“资源所有者”都在线,那么您需要做的是拒绝修改权,因为修改将在服务器端进行,所以更容易实现。在这种情况下,使用WebSockets的解决方案可以很容易地实现,但我不知道做这样的事情的库或框架。很可能你必须自己构建它。

答案 1 :(得分:1)

如果您不限制使用特定的Web框架,请随意尝试以下基于过滤器的针对泽西的实现。请注意,您仍然需要添加相当数量的自定义代码来处理" Collective authentication"因为球衣只提供了所需的基本工具,并没有明确地实现整个概念。以下是您如何在高层次上做到这一点:

class AuthorizationProvider {

    public void authenticate(ContainerRequestContext requestContext) {

        // Here you would need to query your database to get the Collection of Users belonging 
        // to the "Collective" Role. You would then check if they are all logged in.
        // A really abstract version would look like this, assuming you've already queried the DB
        // and have a reference to the above mentioned Collection.

        if (collectiveUsers.size == collectiveUsers.stream().filter(User::isLoggedIn).count()) {
            return true;
        }
        return false;
    }
}

class AuthorizationRequestFilter implements ContainerRequestFilter {

    private final AuthorizationProvider authorizationProvider;

    @Override
    public void filter(ContainerRequestContext requestContext) {

        if (authorizationProvider.authenticate(requestContext)) {
            // serve whatever it is you want to serve if all required users are logged in
        } else {
            // otherwise reject the request
            requestContext.abortWith(Response
                .status(Response.Status.UNAUTHORIZED)
                .entity("Resource available only after collective login")
                .build());
        }
    }
}

@ApplicationPath("/")
class MyApplication extends ResourceConfig {

    public MyApplication() {
        // Register the filter
        register(AuthorizationRequestFilter.class);
    }
}

除此之外,您还需要处理Login部分。 您可以为这些特定用户分配Collective角色,只要他们成功通过登录身份验证,您就会将其标记为已登录。

如果满足上述所有条件,您应该能够成功地为您的" Collective服务"页面,只有当所有" Collective"用户已登录。

这也涵盖了如果其中一个用户注销,则将状态存储在数据库中的部分(使用isLoggedIn = false标记Collective用户)。因此,从这一点开始,每当有人请求页面时,它都会返回Unauthorized。

相反,如果有人注销,您还可以尝试实施SSE(服务器发送事件)以主动更新前端部分。有了这个,即使有人已经设法获得该页面,该页面也将被主动禁用。

容器请求过滤器源和示例,供参考,jersey docs