Spring security openId 支持和用户取消身份验证

Posted

技术标签:

【中文标题】Spring security openId 支持和用户取消身份验证【英文标题】:Spring security openId support and user deauthentication 【发布时间】:2012-05-30 10:52:33 【问题描述】:

我正在尝试处理在通过 openId 提供程序成功验证后发现我的数据库中没有与用户 openId 标识符关联的帐户的情况。

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

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

【问题讨论】:

【参考方案1】:

我认为您可能混淆了两个概念:身份验证授权。身份验证是知道用户是谁,授权是使用访问某个功能的资源的权利。

在 Spring Security 中,这两个概念由 authentication-manageraccess-decision-manager 实现。

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

您不应该在身份验证上接触,而是自定义 access-decision-manager 以应用以下规则:

存在于您数据库中的用户可以访问除帐户创建功能之外的所有内容 您的数据库中不存在的用户只能访问帐户创建功能。

这都是关于访问管理,而不是身份验证。

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

PS:spring security的文档并不详尽,但是源码可读性很强。我的建议是检查一下并查看您需要自定义的元素的实现。

【讨论】:

【参考方案2】:

好的,因此 Samuel 的帖子中提到的将身份验证与授权分开确实很有帮助。但是仍然有很多陷阱,我发现取消身份验证仍然是必须的,因为在春季没有简单的方法可以向用户添加新角色。所以最简单的方法是强制用户再次登录,让spring在登录时处理角色分配。

为了在 Spring Security 中解除用户身份验证,您必须调用:

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;
    

【讨论】:

以上是关于Spring security openId 支持和用户取消身份验证的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 和 OpenID Connect (OIDC)

使用 Spring Security 3.0.2 进行 OpenId 身份验证和自动注册

是否有像 *** 这样的 Spring Security OpenId 注册?

Spring security 3 在使用 OpenID 进行身份验证时忽略禁用/锁定标志

OpenID Connect 的 Spring Security 5 XML 配置

访问令牌实现的spring security openid连接请求不符合cas api要求