登录页面未按预期方式显示注销消息



我正在使用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还需要,但注销的先决条件是用户经过身份验证(。

所以在你的情况下发生的事情是这样的:

  1. 您执行注销并重定向到logoutSuccessUrl作为响应;
  2. 您无权访问logoutSuccessUrl因此正常进程启动:url 保存到会话,然后您获得另一个重定向到登录页面(无参数(;
  3. 当您执行登录时,您会重定向到保存的logoutSuccessUrl并最终看到您的消息。

最新更新