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

我应该如何在Java中的应用程序层之间传递主题/主体/角色?,java,security,authentication,authorization,Java,Security,Authentication,Authorization,我目前有许多web应用程序可以访问运行在JBoss5.0中的公共服务。该服务非常简单,使用Guice和pojo。web应用程序经过身份验证,并且知道用户是谁以及他们扮演什么角色。调用服务时,我应该如何将此身份验证信息传递给服务 似乎最简单的方法就是简单地向界面添加一个参数来获取用户信息。可能是个话题。但这样做的缺点是,界面上的上下文信息并不特定于手头的工作 void doSomething(Subject subject, ...) { } 我看到的另一种选择是使用ThreadLocal存储,

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

似乎最简单的方法就是简单地向界面添加一个参数来获取用户信息。可能是个话题。但这样做的缺点是,界面上的上下文信息并不特定于手头的工作

void doSomething(Subject subject, ...) {
}
我看到的另一种选择是使用ThreadLocal存储,在调用之前将用户信息放在那里,并通过服务可以使用的一些实用程序类使其可访问。这将清理接口,但隐藏服务的客户端在进行调用之前必须设置用户信息的事实


还有别的办法吗?我感觉AOP在这里可能也有用,但不太清楚如何使用。我是否缺少一些“最佳实践”?EJB会有帮助吗?

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

您考虑过将身份验证过程移动到公共服务吗?然后,您只需要公共服务中的会话ID就可以识别请求来自的用户的所有信息

这会清理接口,但隐藏以下事实: 服务必须在拨打电话之前设置用户信息

是的,但是如果您需要在整个应用程序中将某些内容传递给特定的方法,那么您就无法达到使用依赖项注入的目的。它就在那里,这样你就不必把一堆服务和对象传递给其他服务和对象,等等,它们是用它们所需要的一切创建的

还有别的办法吗?我感觉AOP可能是 在这里也很有用,但不太清楚如何使用。有什么“最佳实践”吗 我失踪了?EJB会有帮助吗

另一种方法是在调用需要主题/用户的服务的每个Servlet上使用单个过滤器。在筛选器中设置用户,并在try finally块的末尾清除该用户。事实上,在设置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();
        }
    }
}
@Singleton
公共MyUserFilter扩展了筛选器的个数{
私人最终提供者;
@注入
MyUserFilter(提供程序验证){
this.authProvider=auth;
}
public void doFilter(ServletRequest请求、ServletResponse响应、,
FilterChain链)抛出java.io.IOException、ServletException{
试一试{
//使用请求和/或请求对当前用户进行身份验证和设置
//会话对象
authProvider.get().authenticateUser(HttpRequest currentRequest);
//沿着servlet链继续
…其他处理
}最后{
authProvider.get().getRidOfCurrentUser();
}
}
}
这会清理接口,但隐藏以下事实: 服务必须在拨打电话之前设置用户信息

是的,但是如果您需要在整个应用程序中将某些内容传递给特定的方法,那么您就无法达到使用依赖项注入的目的。它就在那里,这样你就不必把一堆服务和对象传递给其他服务和对象,等等,它们是用它们所需要的一切创建的

还有别的办法吗?我感觉AOP可能是 在这里也很有用,但不太清楚如何使用。有什么“最佳实践”吗 我失踪了?EJB会有帮助吗

另一种方法是在调用需要主题/用户的服务的每个Servlet上使用单个过滤器。在筛选器中设置用户,并在try finally块的末尾清除该用户。事实上,在设置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();
        }
    }
}
@Singleton
公共MyUserFilter扩展了筛选器的个数{
私人最终提供者;
@注入
MyUserFilter(提供程序验证){
this.authProvider=auth;
}
public void doFilter(ServletRequest请求、ServletResponse响应、,
FilterChain链)抛出java.io.IOException、ServletException{
试一试{
//使用请求和/或请求对当前用户进行身份验证和设置
//会话对象
authProvider.get().authenticateUser(HttpRequest currentRequest);
//沿着servlet链继续
…其他处理
}最后{
authProvider.get().getRidOfCurrentUser();
}
}
}

你说得对,依赖注入是一条可行之路。我已经在整个web应用程序和服务中使用了它,但这两者是完全分开的,这就是为什么按照你的建议做并不那么简单的原因。我想我会像你建议的那样使用一个身份验证提供者,然后在impl中使用线程本地存储来设置/访问我的身份验证信息。无论如何,这都会对服务隐藏,因为它只会使用身份验证提供程序。你说得对。Owasp ESAPI目前正在尝试制作一个利用DI的API。我只想确保AuthImpl中的所有其他内容都是线程安全的,并且在使用那些该死的有状态单例时,不要忘记范围扩展注入的危险。祝你好运。你是对的,依赖注入是一条路要走。我在整个web应用程序和