2012-04-17 117 views
0

我用這樣的代碼進行驗證:我不知道是什麼SecurityContextHolder的策略使用

@PreAuthorize("isAnonymous()") 
@RequestMapping(value = "/login", method = RequestMethod.POST) 
public String doLogin(HttpServletRequest request) { 
    try { 
     Authentication req = new UsernamePasswordAuthenticationToken(request.getParameter("name"), 
       request.getParameter("password")); 
     Authentication result = authenticationManager.authenticate(req); 
     SecurityContextHolder.getContext().setAuthentication(result); 
     logger.debug("Success login"); 
     logger.debug(SecurityContextHolder.getContext().getAuthentication()); 
     return "index"; 
    } catch (AuthenticationException e) { 
     e.printStackTrace(); 
     logger.debug("ACHTUNG! Success failed"); 
     return "index"; 
    } 
} 

我可以登錄,它的工作原理。我在日誌中看到非空認證對象。 後來我嘗試瀏覽一些安全網頁是這樣的:

@PreAuthorize("hasRole('user')") 
@RequestMapping(value = "/user", method = RequestMethod.GET) 
public String user(ModelMap modelMap) { 
    modelMap.addAttribute("user", SecurityContextHolder.getContext().getAuthentication().getCredentials().toString()); 
    return "index"; 
} 

而且它拋出,因爲getAuthentication的NullPointerException異常()。 這發生在我使用SecurityContextHolder.MODE_INHERITABLETHREADLOCAL和SecurityContextHolder.MODE_INHERITABLETHREADLOCAL時與使用SecurityContextHolder.MODE_GLOBAL不同。

我在做什麼錯?我不需要SecurityContextHolder的MODE_GLOBAL行爲。

UPD:有時出現問題,有時不在同一個會話中。

+0

確保你的'/ login'網頁沒有'過濾器=「無」'配置:HTTP://計算器.com/questions/3923296/user-granted-authorities-are-always-role-anonymous – axtavt 2012-04-17 12:32:57

+0

您確定NPE來自getAuthentication()的結果(例如Authentication對象爲null)嗎?這是在你登錄的同一個請求中,還是在你從登錄頁面重定向之後? – 2012-04-17 14:25:17

+0

@peter是的,我檢查。由getAuthentication()引起的NPE。不,請求不同。 – 2012-04-17 14:48:52

回答

1

務必確保保安過濾器是由運行記錄每次在您的要求:

request.getAttribute("__spring_security_scpf_applied"); 

不要。除非你完全知道你在做什麼,否則不要替換SecurityContextHolderStrategy。它與查找基於ThreadLocal的SecurityContext有關。所以除非你是一個非常奇怪的Servlet容器,否則默認幾乎總是正確的。

您還需要爲您的請求路徑製作一個攔截器。 @PreAuthorize只適用於方法調用http://static.springsource.org/spring-security/site/docs/3.0.x/reference/el-access.html這不是你想要的。

相反,你想要的東西就像在你的安全應用程序上下文如下:

<http> ... 
     <intercept-url pattern="/user**" access="hasRole('user')" /> 
</http> 
+1

Upvoting,因爲檢查SCPF應用屬性的提示是一個很好的建議,並適用於許多問題 - 好的提示! – 2012-07-25 17:17:37

相關問題