在我们的应用程序中,我们使用JSF& EJB 3.0(EclipseLink 2.0)。我们需要对无状态会话bean中的每个连接使用Oracle代理授权。为此,我们需要获取DB用户名以通过代理连接。 DB用户名由规则的JSF认证用户名构成。
以下是关于主题http://blogs.oracle.com/olaf/2010/04/using_oracle_proxy_authenticat.html
的文章因此,当经过身份验证的用户调用JSF托管bean方法时,该方法会调用某些会话bean方法,他的用户名必须以某种方式传递给会话bean。
现在我有两个不太好的解决方案: - 在每个会话bean方法中将用户名作为参数传递(不是很整洁但会起作用); - 上面文章的解决方案:使用会话bean的类成员变量来存储用户名(不是线程安全且有潜在危险)
P.S。我找到了使用线程局部变量的解决方案:_http://www.adam-bien.com/roller/abien/entry/how_to_pass_context_with 它工作正常,但仍有问题。我需要在每次调用ejb会话bean之前将当前用户名放在每个jsf会话管理bean中,因为它必须位于同一个线程中。
答案 0 :(得分:2)
如果您的用户通过容器进行身份验证,则可以使用javax.ejb.SessionContext
的注入实例来访问ejb中的用户名,如下所示:
@Resource
private SessionContext context;
private String getCurrentUsername() {
return context.getCallerPrincipal().getName();
}
编辑:如果通过login-config和security-constraint元素在web.xml中配置身份验证,则此方法有效。如果您自己进行身份验证,则可以使用ServletFilter和HttpServletRequestWrapper来覆盖getUserPrincipal,getRemoteUser和isUserInRole(在glassfish中测试)。
如果你在jsf bean中处理身份验证,那么这可能不起作用,因为ejb已经初始化并注入了。但是,您也可以创建一个会话范围的ejb,它只保存用户名并将此bean注入您的无状态bean。