2016-04-23 38 views
0

考慮以下情形:春季安全對定製UserDetailsService執行驗證的登錄數據如下如何定製會話的行爲由當前用戶作用域的bean是Spring MVC的

@Override 
    public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException { 
     List<GrantedAuthority> authorities = new ArrayList<>(); 
     authorities.add(new SimpleGrantedAuthority("ROLE_USER")); 

     UserProfile profile = users.find(name); 
     if (profile.getUsername().equals("admin")) 
      authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN")); 

     return new User(profile.getUsername(), profile.getPassword(), authorities); 
    } 

如果認證成功,我想創造出獨特的session scoped service在控制器中,通過有效的UserProfile對象狀態自定義行爲。我想最好的方法是在配置文件中手動聲明會話bean,並以某種方式autowireUserProfile會話所有者它是構造函數,但是如何在UserProfile甚至不是託管對象時可能如此?

在這種情況下,我想服務器創建存儲在UserProfile

另外,如何限制一個建立這樣的服務,爲驗證用戶的服務,保持與憑證SSH連接到遠程主機剛剛登錄後?是否有辦法實現這種行爲,還是實際上是糟糕的架構?

回答

0

您可以使用SecurityContextHolder訪問當前請求的已認證用戶。我認爲最好的辦法是建立一個集服務,像這樣的方法:

public UserDetails getCurrentUser() { 
    Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); 
    if (principal instanceof UserDetails) { 
     return (UserDetails) principal; 
    } else { 
     //handle not authenticated users 
     return null; 
    } 
} 

現在,您可以自動裝配,並在控制器中使用該服務。

+0

我可以將實際的UserProfile對象添加到安全上下文並以相同的方式檢索它嗎?嘗試使用會話作用域bean時,我也遇到以下錯誤:'org.springframework.web.util.NestedServletException:請求處理失敗;嵌套異常是java.lang.IllegalArgumentException:setAttribute:名稱爲scopedTarget.sessionBean的不可序列化屬性 ' –

+0

SecurityContextHolder返回從UserDetailsS​​ervice返回的同一對象。所以你應該可以將它轉換爲'UserProfile'而不是'UserDetails'。我的示例中的服務應該是單例,而不是會話/請求範圍。而異常意味着會話範圍的bean應該是'Serializable'。 – Cyril

+0

更正:你從'UserDetailsS​​ervice'返回'User'。這意味着你不能將其轉換爲'UserProfile'。爲什麼你需要'UserProfile'對象? – Cyril

相關問題