我试图处理一个情况,当与openId提供商成功验证后,我发现我的数据库中没有帐户与用户openId标识符关联。春季安全openId支持和用户解除认证
你能告诉我该如何处理这种情况。现在,我显示注册表单并要求用户创建一个帐户。但是,我有一个用户身份验证状态的问题,他现在被Spring SecurityContext类视为已验证身份。
如何在重定向到“注册新用户页面”之前取消我的控制器操作中的用户身份验证?这种方法是好的,还是应该以其他方式做?
我试图处理一个情况,当与openId提供商成功验证后,我发现我的数据库中没有帐户与用户openId标识符关联。春季安全openId支持和用户解除认证
你能告诉我该如何处理这种情况。现在,我显示注册表单并要求用户创建一个帐户。但是,我有一个用户身份验证状态的问题,他现在被Spring SecurityContext类视为已验证身份。
如何在重定向到“注册新用户页面”之前取消我的控制器操作中的用户身份验证?这种方法是好的,还是应该以其他方式做?
好的,所以在Samuel的文章中提到的将授权与授权分开是非常有用的。然而,仍然有很多问题,我发现解除认证仍然是必须的,因为在春季没有简单的方法来添加用户新的角色。所以最简单的方法是强制用户再次登录,并在登录时让弹簧处理角色分配。
为了deauthenticate用户在春季安全,你必须调用:
SecurityContextHolder.clearContext();
作为替代你可以在你的UserDetailsService实现抛出一个异常(见下文)。它有缺点,你将取消用户验证并丢失用户上下文数据,因此在创建新本地帐户的过程中,不可能将新用户帐户与openid帐户相匹配。用户登录后必须使用传统的用户名和密码来匹配这些帐户。我的解决方案是在创建新帐户后立即取消用户验证。
为了给予用户角色(权限),你需要重写的UserDetailsService,万一有人在这里找到这个有用的是我实现:
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;
}
}
我认为你可能会混合两个概念:身份验证和授权。认证是知道用户是谁,授权是使用权限访问特征资源的权利。
春天的安全,这两个概念是由认证经理和访问决策管理实现。
用户在您的数据库中不存在的事实不是拒绝他的理由是身份:没有解除身份验证!但是,通过身份验证可以成为访问决策管理中的一个标准。例如:AuthenticatedVoter。
你不应该在认证碰,但自定义访问决策管理器应用以下规则:
这是关于访问管理,而不是认证。
PS:文档不是弹簧安全穷举的,但源代码是非常可读的。我的建议是查看它并查看您需要自定义的元素的实现。