Java Spring安全性登录/注销问题
我正在使用Spring4.3.3,我正在尝试为我的应用程序实现登录/注销功能。我遇到的问题是,如果我立即登录并再次注销,所有工作都会按预期进行。我被带到登录页面的URL:login?注销,登录框中有一条成功注销的消息。但是,如果我登录并导航到另一个页面,然后注销,我将再次正确进入登录页面,并在登录框中显示成功注销消息,但当我单击登录时,我未登录。相反,我使用了一个URL登录:登录时不显示任何消息,我需要再次单击登录才能登录。下面是我正在使用的一些代码 security.xmlJava Spring安全性登录/注销问题,java,spring,spring-mvc,spring-security,Java,Spring,Spring Mvc,Spring Security,我正在使用Spring4.3.3,我正在尝试为我的应用程序实现登录/注销功能。我遇到的问题是,如果我立即登录并再次注销,所有工作都会按预期进行。我被带到登录页面的URL:login?注销,登录框中有一条成功注销的消息。但是,如果我登录并导航到另一个页面,然后注销,我将再次正确进入登录页面,并在登录框中显示成功注销消息,但当我单击登录时,我未登录。相反,我使用了一个URL登录:登录时不显示任何消息,我需要再次单击登录才能登录。下面是我正在使用的一些代码 security.xml <http
<http pattern="/resources/**" security="none"/>
<http pattern="/forgot**" security="none"/>
<http pattern="/reset**" security="none" />
<!-- enable use-expressions -->
<security:http
auto-config="false"
use-expressions="true">
<headers><cache-control/></headers>
<security:intercept-url pattern="/resources**" access="permitAll" />
<security:intercept-url pattern="/login**" access="permitAll" />
<security:intercept-url pattern="/users**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
<security:intercept-url pattern="/suppliers**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
<security:intercept-url pattern="/reports**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
<security:intercept-url pattern="/games**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
<security:intercept-url pattern="/clients**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
<security:intercept-url pattern="/servers**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')" />
<security:intercept-url pattern="/**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/>
<security:intercept-url pattern="/logs**" access="hasAnyRole('ROLE_USER','ROLE_ADMIN')"/>
<!-- access denied page -->
<access-denied-handler error-page="/403" />
<security:form-login
login-page="/login"
authentication-failure-url="/login?error"
username-parameter="username"
password-parameter="password"
login-processing-url="/auth/login_check" />
<security:logout
invalidate-session="true"
logout-success-url="/login"
logout-url="/login?logout"
delete-cookies="JSESSIONID"/>
<!-- enable csrf protection -->
<csrf/>
<!-- Default lifeTime 2 weeks can be configured -->
<!--<remember-me key="uniqueAndSecret"/>-->
</security:http>
login.jsp
<form name='loginForm' action="<c:url value='/auth/login_check?targetUrl=${targetUrl}' />" method='POST'>
<div class="form-group">
<div id="emailError" class="alert alert-danger" style="display:none;"></div>
<label for="email">Email
<input class="form-control" id="email" type="email" name="username" placeholder="Email">
</label>
</div>
<div class="form-group">
<label for="password">Password
<input class="form-control" id="password" type="password" name="password" placeholder="Password">
</label>
</div>
Remember Me: <input type="checkbox" name="remember-me" />
<input id="login"class="btn btn-primary" name="submit" type="submit" value="Login">
<div><a id="forgotPass">forgot password</a></div>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
</form>
电子邮件
密码
记住我:
忘记密码
从您的安全配置判断,我不确定您是否正在使用CookiesRftokenRepository
。我看到您在注销时手动使所有cookie过期:
for(Cookie cookie : request.getCookies()) {
cookie.setMaxAge(0);
}
除非您在应用程序中手动设置了其他cookie,否则会话cookie将默认删除,因为您已将其配置为:
<security:logout
...
delete-cookies="JSESSIONID"/>
我猜您也在清除CSRF令牌cookie,因此在没有令牌的情况下呈现的登录页面。由于CSRF不匹配,提交表单可能会自动失败,从而使您返回登录页面。这一次,将再次设置CSRF值,随后的登录尝试将成功。Hi,不确定。我只是在看一个教程,上面有两个星号。您能解释一下为什么/logs**永远不会命中吗?您不应该将“/auth”添加到“允许所有”列表中吗?@dur,因为表单方法设置了auth/login\u check,所以Spring会将这些请求作为“登录处理url”来处理吗?另一个想法是重定向发生是因为它有targetUrl=somereference,配置是否会被修改为通配符匹配登录处理url=“/auth/login_check*”?您好@frederik heremans感谢您的回复。我想这就是问题所在。我从使会话和Cookie过期的控制器中删除了代码,它按预期工作。然而,我注意到了另一个问题。一旦我注销。如果我手动编辑URL,我将被正确重定向到登录页面,但如果我单击“上一步”,我将被带到上一页并仍然登录。正如@dur所述,“Spring Security为您完成了此操作,您已经配置了它。”。您可以使用spring安全注销机制(它处理您的会话失效),或者在控制器中实现您自己的“注销”逻辑(您正在这样做),在这里您仍然需要使会话失效。这将触发重定向到登录页面,因为不存在有效凭据,并且spring安全性将启动。。。
<security:logout
...
delete-cookies="JSESSIONID"/>