我正在使用Spring Security
版本4.2.3.RELEASE
- 必须使用
csrf
。
我使用了以下内容对login.jsp
文件,5.3 Java 配置和表单登录的引用,因此我有:
<body>
<spring:url var="loginUrl" value="/perform_/login"/>
<form name="login" action="${loginUrl}" method="POST">
<fieldset class="fieldset">
<legend><spring:message code="login.legend"/></legend>
<c:if test="${param.error != null}">
<p class="error"><spring:message code="login.invalid"/></p>
</c:if>
<c:if test="${param.logout != null}">
<p><spring:message code="logout.valid"/></p>
</c:if>
<table>
.... fields for username and password and submit button ...
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
</form>
在其他.jsp
页面中存在注销目的:
<spring:url var="logoutUrl" value="/perform/logout" />
<form id="logoutForm" action="${logoutUrl}" method="post">
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
<a href="javascript:formSubmit()"><spring:message code="logout.title"/></a>
</form>
<script>
function formSubmit() {
document.getElementById("logoutForm").submit();
}
</script>
最后,通过Javaconfig for Spring Security,存在以下内容:
.formLogin()
.loginPage("/perfom/login")
.loginProcessingUrl("/perform_/login")
.usernameParameter("username")//default
.passwordParameter("password")//default
.defaultSuccessUrl("/welcome")
.failureUrl("/perfom/login?error") //default is /login?error
.permitAll()
.and()
.logout()
.logoutUrl("/perform/logout")//default is /logout
.logoutSuccessUrl("/perfom/login?logout")//default is /login?logout
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID");
注意:/perfom/login
用于:
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/message").setViewName("general/message");
registry.addViewController("/welcome").setViewName("general/welcome");
registry.addViewController("/perfom/login").setViewName("login/login");
}
加载登录页且用户名或密码值不正确时,将再次加载同一登录页并显示错误消息。因此<c:if test="${param.error != null}">
工作正常。
问题是当注销事件发生时,它会按预期方式进入login.jsp
页面,但没有显示注销消息。但是,如果在那一刻我尝试使用有效值进行登录,则会再次加载相同的login.jsp
页面,然后出现注销消息。
我做了一个研究,"似乎"纠正了我的配置,即使根据这个:
- 如何在自定义登录页面中获取注销消息
需要什么缺少的配置?
TL;DR您需要在deleteCookies("JSESSIONID")
之后添加另一个permitAll()
呼叫。
根据文档permitAll()
FormLoginConfigurer
确保 failureUrl(String( 和 HttpSecurityBuilder、getLoginPage 和 getLoginProcessingUrl 的 url 被授予任何用户访问权限。
但是您还需要授予对logoutSuccessUrl
的访问权限(为了公平访问logoutUrl
还需要,但注销的先决条件是用户经过身份验证(。
所以在你的情况下发生的事情是这样的:
- 您执行注销并重定向到
logoutSuccessUrl
作为响应; - 您无权访问
logoutSuccessUrl
因此正常进程启动:url 保存到会话,然后您获得另一个重定向到登录页面(无参数(; - 当您执行登录时,您会重定向到保存的
logoutSuccessUrl
并最终看到您的消息。