我試圖處理一個情況,當與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:文檔不是彈簧安全窮舉的,但源代碼是非常可讀的。我的建議是查看它並查看您需要自定義的元素的實現。