java - spring security注销导致NullPointerException

标签 java spring spring-security

一段时间以来,我一直在努力理解 spring-security,除了 logout 方面之外,我已经了解了大部分内容。通过其他关于 SO 的问题,我觉得他们中的大多数都面临与 session 不终止相关的问题。

另一方面,我面临着完全不同的麻烦。我的安全 XML 文件配置如下:

<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)

感谢您抽出宝贵时间。

最佳答案

AbstractAuthenticationTargetUrlRequestHandler 中的determineTargetUrl 方法似乎无法获取请求参数。对我来说,通常可以提供一个 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 定义 bean 时,在安全上下文中将注销 URL 设置为 defaultTargetUrl:

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

关于java - spring security注销导致NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7325655/

相关文章:

java - getMessage 的设计模式

JavaFX:支持不同分辨率

spring-security - spring security 3.2.0 csrf token 在 freemarker 模板中不起作用

java - 使用 Spring Security 的 SpringMVC Websockets 消息传递用户身份验证

java - 为什么 SAXException 是可序列化的?

java - 用于解析 xml 的正则表达式问题

java - 从@Valid 验证中排除某些字段

java - Spring Controller Advice异常处理程序总是返回404

java - 如何在下拉列表中加载未使用ID的值...隐藏其值已使用的所有记录?

java - 在登录页面上实现 HDIV