2012-05-23 55 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:文檔不是彈簧安全窮舉的,但源代碼是非常可讀的。我的建議是查看它並查看您需要自定義的元素的實現。