2012-05-23 56 views
5

我试图处理一个情况,当与openId提供商成功验证后,我发现我的数据库中没有帐户与用户openId标识符关联。春季安全openId支持和用户解除认证

你能告诉我该如何处理这种情况。现在,我显示注册表单并要求用户创建一个帐户。但是,我有一个用户身份验证状态的问题,他现在被Spring SecurityContext类视为已验证身份。

如何在重定向到“注册新用户页面”之前取消我的控制器操作中的用户身份验证?这种方法是好的,还是应该以其他方式做?

回答

2

好的,所以在Samuel的文章中提到的将授权与授权分开是非常有用的。然而,仍然有很多问题,我发现解除认证仍然是必须的,因为在春季没有简单的方法来添加用户新的角色。所以最简单的方法是强制用户再次登录,并在登录时让弹簧处理角色分配。

为了deauthenticate用户在春季安全,你必须调用:

SecurityContextHolder.clearContext(); 

作为替代你可以在你的UserDetailsS​​ervice实现抛出一个异常(见下文)。它有缺点,你将取消用户验证并丢失用户上下文数据,因此在创建新本地帐户的过程中,不可能将新用户帐户与openid帐户相匹配。用户登录后必须使用传统的用户名和密码来匹配这些帐户。我的解决方案是在创建新帐户后立即取消用户验证。

为了给予用户角色(权限),你需要重写的UserDetailsS​​ervice,万一有人在这里找到这个有用的是我实现:

public final class MyUserDetailsService implements UserDetailsService { 
    private final UsersDao usersDao; 

    @Autowired 
    public UserDetailsServiceImpl(final UsersDao usersDao) { 
     this.usersDao = usersDao; 
    } 

    @Override 
    public UserDetails loadUserByUsername(final String username) {  
      UserEntity user = usersDao.getUserByOpenIdIdentifier(username); 
      if (user == null) { 
        // there is no such user in our db, we could here throw 
        // an Exception instead then the user would also be deuthenticated 
        return new User(username, "", new ArrayList<GrantedAuthority>()); 
      } 

      //here we are granting to users roles based on values from db 
      final Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(); 
      authorities.add(new SimpleGrantedAuthority(user.getUserType().toString())); 

      final UserDetails result = new User(username, "", authorities); 

      return result; 
    } 
} 
1

我认为你可能会混合两个概念:身份验证授权。认证是知道用户是谁,授权是使用权限访问特征资源的权利。

春天的安全,这两个概念是由认证经理访问决策管理实现。

用户在您的数据库中不存在的事实不是拒绝他的理由是身份:没有解除身份验证!但是,通过身份验证可以成为访问决策管理中的一个标准。例如:AuthenticatedVoter。

你不应该在认证碰,但自定义访问决策管理器应用以下规则:

  • 谁在数据库中存在的用户可以访问一切,除了账号创建功能
  • 数据库中不存在的用户只能访问帐户创建功能。

这是关于访问管理,而不是认证。

阅读更多http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html#ns-access-manager

PS:文档不是弹簧安全穷举的,但源代码是非常可读的。我的建议是查看它并查看您需要自定义的元素的实现。