2011-09-06 141 views
8

我一直在嘗試瞭解彈簧安全一段時間,並且除了logout方面外,我已經瞭解了大多數情況。在討論其他問題時,我覺得他們中的大多數都面臨着與會議沒有終止有關的問題。另一方面,我正面臨着相當不同的麻煩。我的安全XML文件配置如下:春季安全註銷導致NullPointerException

<http path-type="ant" auto-config="false" use-expressions="true" 
    access-denied-page="/?login_error=2"> 
    <intercept-url pattern="/web/open/**" access="permitAll" /> 
    <intercept-url pattern="/web/**" access="isAuthenticated()" /> 

    <form-login login-processing-url="/static/j_spring_security_check" 
     default-target-url="/web/base/view" always-use-default-target="true" 
     login-page="/" authentication-failure-url="/?login_error=1" /> 

    <logout logout-url="/static/j_spring_security_logout" 
     invalidate-session="true" logout-success-url="/" /> 
</http> 

在我web.xml我已經映射到login controller上下文根[使用welcome-file列表],也有需要springSecurityFilterChain設置。現在登錄操作完美運行。目標JSP有一個註銷鏈接爲:

<a href="<c:url value="/static/j_spring_security_logout"/>">Logout</a> 

但是,每當我點擊登出鏈接,我得到一個可怕的NullPointerException。任何人都可以告訴我,如果我在這裏製造一些明顯的錯誤?


異常堆棧:

java.lang.NullPointerException 
    at java.util.Hashtable.get(Hashtable.java:334) 
    at org.apache.tomcat.util.http.Parameters.getParameterValues(Parameters.java:116) 
    at org.apache.tomcat.util.http.Parameters.getParameter(Parameters.java:127) 
    at org.apache.catalina.connector.Request.getParameter(Request.java:1133) 
    at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:384) 
    at javax.servlet.ServletRequestWrapper.getParameter(ServletRequestWrapper.java:140) 
    at org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler.determineTargetUrl(AbstractAuthenticationTargetUrlRequestHandler.java:86) 
    at org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler.handle(AbstractAuthenticationTargetUrlRequestHandler.java:67) 
    at org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler.onLogoutSuccess(SimpleUrlLogoutSuccessHandler.java:28) 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:100) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:381) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:168) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) 

感謝您抽出寶貴的時間。

回答

12

determineTargetUrl方法AbstractAuthenticationTargetUrlRequestHandler似乎無法獲取請求參數。對我來說,通常可以提供defaultTargetUrl並將alwaysUseDefaultTargetUrl設置爲true,這通常是determineTargetUrl總是返回給定的URL並阻止URL確定的魔法。

我會做到這一點,通過註冊自己LogoutSuccessHandler實現,如:

<logout 
    logout-url="/static/j_spring_security_logout" 
    invalidate-session="true" 
    success-handler-ref="myLogoutSuccessHandler" /> 

,而不是logout-success-url

一個LogoutSuccessHandler可以看看簡單:

public class MyLogoutSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler implements LogoutSuccessHandler { 

    @Override 
    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication throws IOException, ServletException { 
     // maybe do some other things ... 
     super.handle(request, response, authentication); 
    } 
} 

定義豆自定義LogoutSuccessHandler時,設置您註銷URL爲defaultTargetUrl在安全方面:

<bean id="myLogoutSuccessHandler" class="foobar.impl.MyLogoutSuccessHandler"> 
    <property name="defaultTargetUrl" value="/" /> 
    <property name="alwaysUseDefaultTargetUrl" value="true" /> 
</bean> 
+0

'延伸AbstractAuthenticationTargetUrlRequestHandler實現LogoutSuccessHandler'可以由'extends SimpleUrlLogoutSuccessHandler'來代替。 – lschin

+0

gee - 你的建議確實有用,但它對我沒有任何意義。沒有任何文件提到這樣的事情。我不明白,爲什麼不''註銷'沒有'ref-handler'工作? – anirvan

+2

@Ischin:實際上你根本不需要你自己的實現。 '的 ...'是不夠的 - 但也許你想要做一些其他的事情。 – jeha