我应该如何在Java中的应用程序层之间传递主题/主体/角色?

时间:2012-02-24 17:01:57

标签: java security authentication authorization

我目前有许多Web应用程序可以访问JBoss 5.0中运行的公共服务。使用Guice和POJO,服务非常简单。 Web应用程序经过身份验证,知道用户是谁以及他们拥有什么角色。在调用服务时,我应该如何将此身份验证信息传递给服务?

看起来简单的方法是简单地向接口添加参数以获取用户信息。可能是一个主题。但是这有一个缺点,即使用与手头工作无关的上下文信息来混淆界面。

void doSomething(Subject subject, ...) {
}

我看到的替代方法是使用ThreadLocal存储,在进行调用之前将用户信息放在那里,并通过服务可以使用的某个实用程序类来访问它。这样可以清理界面,但隐藏了服务客户端在拨打电话之前必须设置用户信息的事实。

还有另一种方法吗?我觉得AOP也可能在这里使用,但不太明白。我缺少一些“最佳实践”吗? EJB会帮忙吗?

2 个答案:

答案 0 :(得分:1)

  

这清理了界面但隐藏了客户端的事实   服务必须在拨打电话之前设置用户信息。

是的,但是如果你需要在整个应用程序中传递一些特定的方法,那么你就是在挫败使用依赖注入的目的。它就是为了让你不必将一堆服务和对象传递给其他服务和对象等等,它们就是用它们所需的一切创建的。

  

还有另一种方法吗?我感觉AOP可能是   在这里使用,但不能完全看到如何。有一些“最佳实践”   我失踪了? EJB会帮忙吗?

另一种方法是在每个调用需要Subject / User的服务的Servlet上使用单个过滤器。在筛选器中设置用户,并在try-finally块中清除最后的用户。事实上,OWASP Esapi在设置ThreadLocalUser时使用此样式,它允许用户在应用程序的每个部分都可用。

这样的事情:

@Singleton
public MyUserFilter extends FilterOfTheMonth {

    private final Provider<Authenticator> authProvider;

    @Inject
    MyUserFilter(Provider<Authenticator> auth) {
        this.authProvider = auth;
    }

    public void doFilter(ServletRequest request, ServletResponse response, 
            FilterChain chain) throws java.io.IOException, ServletException {
        try {
            // Authenticate and SET the current user utilizing the request and/or                       
            // session objects
            authProvider.get().authenticateUser(HttpRequest currentRequest);

            // Continue on here along the servlet chain
            ... other processing
        } finally {
            authProvider.get().getRidOfCurrentUser();
        }
    }
}

答案 1 :(得分:0)

您是否考虑过将身份验证过程转移到公共服务?然后,您只需要公共服务中的会话ID来标识有关请求来自的用户的所有信息。