Spring安全性openId支持和用户解除身份验证

0lu*_*sz0 5 java openid spring-security java-ee single-sign-on

我试图处理一种情况,在使用openId提供程序成功进行身份验证后,我发现我的数据库中没有与用户openId标识符关联的帐户.

你能告诉我怎样处理这种情况.现在,我正在显示注册表单并要求用户创建一个帐户.但是,我遇到了用户身份验证状态的问题,现在他被Spring SecurityContext类看作是经过身份验证的.

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

0lu*_*sz0 2

好吧,正如塞缪尔的帖子中提到的那样,将身份验证与授权分开确实很有帮助。然而,仍然存在许多问题,我发现解除身份验证仍然是必须的,因为在 Spring 中没有简单的方法来向用户添加新角色。所以最简单的方法就是强制用户重新登录,让spring在登录时处理角色分配。

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

SecurityContextHolder.clearContext();
Run Code Online (Sandbox Code Playgroud)

作为替代方案,您可以在 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;
    }
}
Run Code Online (Sandbox Code Playgroud)