我目前有许多Web应用程序可以访问JBoss 5.0中运行的公共服务。使用Guice和POJO,服务非常简单。 Web应用程序经过身份验证,知道用户是谁以及他们拥有什么角色。在调用服务时,我应该如何将此身份验证信息传递给服务?
看起来简单的方法是简单地向接口添加参数以获取用户信息。可能是一个主题。但是这有一个缺点,即使用与手头工作无关的上下文信息来混淆界面。
void doSomething(Subject subject, ...) {
}
我看到的替代方法是使用ThreadLocal存储,在进行调用之前将用户信息放在那里,并通过服务可以使用的某个实用程序类来访问它。这样可以清理界面,但隐藏了服务客户端在拨打电话之前必须设置用户信息的事实。
还有另一种方法吗?我觉得AOP也可能在这里使用,但不太明白。我缺少一些“最佳实践”吗? EJB会帮忙吗?
答案 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来标识有关请求来自的用户的所有信息。