Spring Security 4.1默认logout-url(/ logout)似乎不起作用

时间:2017-08-28 15:31:20

标签: java spring-security logout apache-tiles

我正在试验Spring安全性,我遇到了一个问题,我现在几乎无法解决。我的默认/登录URL的登录表单工作正常,csrf已启用。调用 MyAuthenticationSuccessHandler 中的 onAuthenticationSuccess 方法,并在成功登录后重定向到所需的页面。我的问题涉及/注销URL。我搜索了许多页面寻求解决方案,但无法找到合适的答案。当我试图通过header.jsp HTTP状态405中的/ logout URL注销时?显示不允许的方法页面,消息为请求方法' POST'不支持。我是通过POST

发送退出表单的

<form id="logoutForm" action="${pageContext.request.contextPath}/logout" method="POST" > <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> </form>

调用 MyLogoutSuccessHandler 中的

onLogoutSuccess 方法并注销用户,但重定向在/ logout URL上停止,并显示该405错误页面。它无法达到 MyLogoutSuccessHandler 中指定的/loginController/showLogout重定向。我无法弄清楚搞砸了什么

这是我的代码:

安全-context.xml中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.1.xsd
    http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.3.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

<jee:jndi-lookup jndi-name="jdbc/spring" id="dataSource"
    expected-type="javax.sql.DataSource">
</jee:jndi-lookup>

<bean id="activeUserStore" class="com.springtutorial.authentication.ActiveUserStore" />

<bean id="myAuthenticationSuccessHandler"
    class="com.springtutorial.authentication.MyAuthenticationSuccessHandler">
    <property name="activeUserStore" ref="activeUserStore"></property>
</bean>

<bean id="myLogoutSuccessHandler"
    class="com.springtutorial.authentication.MyLogoutSuccessHandler" />

<security:authentication-manager>
    <security:authentication-provider >
        <security:jdbc-user-service
            data-source-ref="dataSource"
            users-by-username-query="select username, password, enabled from simple_users where binary username = ?"
            authorities-by-username-query="select username, role from authorities where binary username = ?" />
        <security:password-encoder ref="passwordEncoder"></security:password-encoder>
    </security:authentication-provider>
</security:authentication-manager>
<security:http use-expressions="true">
    <security:intercept-url pattern="/loggedUsers"
        access="hasRole('ROLE_ADMIN')" />
    <security:intercept-url pattern="/adminPage"
        access="hasRole('ROLE_ADMIN')" /> 
    <security:intercept-url pattern="/offerController/processCreateOfferForm"
        access="isAuthenticated()" />
    <security:intercept-url pattern="/offerController/showCreateOfferForm"
        access="isAuthenticated()" />
    <security:intercept-url pattern="/offerController/offerCreated"
        access="isAuthenticated()" />
    <security:intercept-url pattern="/" access="permitAll" />
    <security:intercept-url pattern="/showAccessDenied"
        access="permitAll" />
    <security:intercept-url pattern="/loginController/showRegisterUserForm"
        access="permitAll" />
    <security:intercept-url pattern="/loginController/processRegisterUserForm"
        access="permitAll" />
    <security:intercept-url pattern="/loginController/userRegistered"
        access="permitAll" />
    <security:intercept-url pattern="/loginController/showLoginForm"
        access="permitAll" />
    <security:intercept-url pattern="/loginController/showLogout"
        access="permitAll" />
    <security:intercept-url pattern="/resources/**"
        access="permitAll" />
    <security:intercept-url pattern="/offerController/showOffers"
        access="permitAll" />
    <security:intercept-url pattern="/**" access="denyAll" />
    <security:form-login login-page="/loginController/showLoginForm"
        authentication-failure-url="/loginController/showLoginForm?error=true"
        authentication-success-handler-ref="myAuthenticationSuccessHandler" />
    <security:logout invalidate-session="true"
        success-handler-ref="myLogoutSuccessHandler" />
    <security:access-denied-handler error-page="/showAccessDenied" />
    <security:remember-me key="offersAppKey" />
    <security:csrf />
</security:http>

<bean id="passwordEncoder"
    class="org.springframework.security.crypto.password.StandardPasswordEncoder">
</bean>

我正在使用apache tiles 3进行查看,并且我在loginForm.jsp磁贴中重定向到默认/登录URL: 的 loginForm.jsp中

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<script type="text/javascript">
    $(document).ready(function() {
        document.username.focus()
    });
</script>
    <h3>My Login</h3>

    <c:if test="${param.error}">

    <p class="errors">Login failed. Username or password are wrong.</p>

    </c:if>

    <form  action='${pageContext.request.contextPath}/login' method='POST'>

        <table>
            <tr>
                <td>User:</td>
                <td><input type='text' id='username' name='username' ></td>
            </tr>
            <tr>
                <td>Password:</td>
                <td><input type='password' name='password' /></td>
            </tr>
            <tr>
                <td>Remember me:</td>
                <td><input type='checkbox' name='remember-me' checked="checked" /></td>
            </tr>
            <tr>
                <td colspan='2'><input name="submit" type="submit"
                    value="Login" /></td>
            </tr>
            <tr>
                <td><input name="_csrf" type="hidden"
                    value="${_csrf.token}" /></td>
            </tr>
        </table>
    </form>
    <p><a href="<c:url value="showRegisterUserForm"/>">Create new User</a></p>

并重定向到header.jsp tile中的default / logout URL:

header.jsp中

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="sec"
    uri="http://www.springframework.org/security/tags"%>

<a class="title"
        href="${pageContext.request.contextPath}/">Offers</a>   

<sec:authorize access="!isAuthenticated()">
    <a class="login"
        href="${pageContext.request.contextPath}/loginController/showLoginForm">Login</a>
</sec:authorize>

<sec:authorize access="isAuthenticated()">
    <!-- <a class="login" href="${pageContext.request.contextPath}/logout">Logout</a> -->
    <a class="login" id="logoutLink" href="#">Logout</a>
    <form id="logoutForm" action="${pageContext.request.contextPath}/logout" method="POST" >
          <input type="hidden" name="${_csrf.parameterName}"
            value="${_csrf.token}" />
    </form> 
</sec:authorize>

<script type="text/javascript">
    $(document).ready(function() {
        $('#logoutLink').click(function() {
            $('#logoutForm').submit();
        });
    });
</script>

这些是 AuthenticationSuccessHandler LogoutSuccessHandler 的实现:

MyAuthenticationSuccessHandler

public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {

    @Autowired
    private ActiveUserStore activeUserStore;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) throws IOException, ServletException {
        SavedRequest savedRequest = new HttpSessionRequestCache().getRequest(request, response);
        HttpSession session = request.getSession(false);
        if (session != null) {
            LoggedUser user = new LoggedUser(authentication.getName(), activeUserStore);
            session.setAttribute("user", user);
        }

        if (savedRequest == null) {
            getRedirectStrategy().sendRedirect(request, response, "/");
        } else {
            String targetUrl = savedRequest.getRedirectUrl();
            getRedirectStrategy().sendRedirect(request, response, targetUrl);
        }
    }

    public ActiveUserStore getActiveUserStore() {
        return activeUserStore;
    }

    public void setActiveUserStore(ActiveUserStore activeUserStore) {
        this.activeUserStore = activeUserStore;
    }

}

MyLogoutSuccessHandler

public class MyLogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {

@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
        throws IOException, ServletException {
    System.out.println("co jest");
    HttpSession session = request.getSession();
    if (session != null) {
        session.removeAttribute("user");
    }

    String URL = request.getContextPath() + "/loginController/showLogout";
    getRedirectStrategy().sendRedirect(request, response, URL);
}

}

我实现了这些,因为我想跟踪登录的用户:)

0 个答案:

没有答案