2013-10-28 37 views
0

我试图在我的seam应用程序中更改身份验证方法。我目前使用登录表单进行身份验证。将来,我想将身份验证委托给另一个层,该层将使用包含经过身份验证的用户的用户名的特定HTTP头重写每个请求。找不到使用接缝管理持久性上下文的实体

我正面临一个奇怪的问题:当使用登录页进行身份验证时,我能够通过entityManager提取用户。但是当我使用关于标题的信息查询entityManager时,我无法找到用户。 entityManager的行为就像用户不存在一样。

我已经尝试过两种方法:

  • 创建触发认证过程
  • 创建一个servlet它得到的请求,并开始 认证过程

两次都是假的登录页面,entityManager无法返回任何用户。

我读了很多关于seam如何管理持久化上下文的知识,但是我没有找到解决这个问题的唯一解释。你有什么想法?建议?甚至猜测?

其使用的EntityManager的代码如下:

@Name("userService") 
@AutoCreate 
public class UserService { 
    @Logger 
    private Log logger; 

    @In 
    private EntityManager entityManager; 

    public User getUser(String email) { 
      try { 
       return entityManager 
         .createQuery("SELECT u FROM User u where u.email=:email", 
           User.class).setParameter("email", email.trim()) 
         .getSingleResult(); 
      } catch (NoResultException e) { 
       return null; 
      } 
    } 
} 

用于持久性上下文的配置是:

<persistence:managed-persistence-context startup="false" scope="stateless" 
     auto-create="true" name="entityManager" persistence-unit-jndi-name="java:/EntityManagerFactory" /> 

我创建一个空的假登录页面,其执行页面动作(认证)其中我得到请求用户标头,如下所示:

@Name("applicationAuthenticator") 
public class ApplicationAuthenticator { 
    @Logger 
    private Log log; 

    @In 
    private Identity identity; 
    @In 
    private Credentials credentials; 
    @In(required=true) 
    private UserService userService; 

@Begin 
    public void login() throws LoginException { 
     HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest(); 
     String userName=request.getHeader("user"); 
     identity.unAuthenticate(); 
     credentials.setUsername(userName); 
     credentials.setPassword("fake"); 
     identity.acceptExternallyAuthenticatedPrincipal(new SimplePrincipal(credentials.getUsername())); 
     User user=userService.getUserByEmail(credentials.getUsername()); 
     identity.authenticate(); 
     identity.quietLogin(); 
    } 
} 

THX提前:-)

+0

你能发表一些代码吗?特别是使用实体管理器的位 – DaveB

+0

看来,一个seam拦截器(hibernate安全拦截器,我猜)是禁止通过entityManager.do访问数据源你有任何想法如何禁用或绕过只是休眠安全拦截器? –

+0

您是否检查过字符串实际上是从头中取出的?如果是这样的查询实际执行?也可能是显而易见的,但是你的UserService类是受限制的吗? – DaveB

回答

0

THX @DaveB您的回复,它使用的EntityManager的代码如下:

public User getUser(String email) { 
     try { 
      return entityManager 
        .createQuery("SELECT u FROM User u where u.email=:email", 
          User.class).setParameter("email", email.trim()) 
        .getSingleResult(); 
     } catch (NoResultException e) { 
      return null; 
     } 
    } 

的持久化上下文的配置是:

<persistence:managed-persistence-context startup="false" scope="stateless" 
     auto-create="true" name="entityManager" persistence-unit-jndi-name="java:/EntityManagerFactory" /> 

我创建一个空的虚假登录页面,执行一个页面动作(身份验证),其中我得到请求用户标题如下:

HttpServletRequest request = (HttpServletRequest) FacesContext 
       .getCurrentInstance().getExternalContext().getRequest(); 
     String userName = request.getHeader("user"); 
+0

所以你所说的是,上面的查询在被作为页面动作调用时不会给出任何结果,但是当它从标准登录表单被调用时,它确实能够工作......?你可以发布整个支持bean /类,特别是如何获取您的entityManager实例。 – DaveB

+0

btw。你应该添加这个额外的细节问题不作为答案 – DaveB

+0

Thx DaveB为您的快速回复:),我更新了更多的代码细节问题。我说的是,查询确实工作使用登录表单(提交按钮的形式执行页面动作),但是当我发送一个HTTP GET请求(与用户头)到一个页面动作(applicationAuthenticator.login)查询不起作用(userService.getUser返回空)。 –

相关问题