Вход и выход из Spring безопасности

Я хочу создать веб-приложение, используя Spring Security, но чувствую, что что-то не так или чего-то не хватает.

Вот мои коды:

безопасность.xml:

<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/security
       http://www.springframework.org/schema/security/spring-security.xsd">

<http use-expressions="true" disable-url-rewriting="true">
    <intercept-url pattern="/index.htm" access="hasRole('ROLE_ADMIN')" />
    <form-login login-processing-url="/login" login-page="/login.htm"
        username-parameter="userName" password-parameter="password"
        default-target-url="/index.htm" always-use-default-target="true"
        authentication-failure-url="/login.htm?auth=fail" />
    <logout logout-url="/logout.htm" logout-success-url="/login?out=1"
        delete-cookies="JSESSIONID" invalidate-session="true" />
</http>

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="drs" password="123456" authorities="ROLE_ADMIN" />
            <user name="dr" password="123456" authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>
</beans:beans>

контроллер:

@Controller
public class SecurityController {
    @RequestMapping(value = "/logout.htm", method = RequestMethod.GET)
    public String logoutPage() {
        return "logoutPage";
    }

    @RequestMapping(value = "/login.htm", method = RequestMethod.GET)
    public String login() {
        return "loginPage";
    }
}

логин.jsp:

<form:form action="${pageContext.request.contextPath}/login" method="POST">
    <c:if test="${not empty param.err}">
        <div>
            <c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" />
        </div>
    </c:if>
    <c:if test="${not empty param.out}">
        <div>You've logged out successfully.</div>
    </c:if>
    <c:if test="${not empty param.time}">
        <div>You've been logged out due to inactivity.</div>
    </c:if>

    Username:<br>
    <input type="text" name="userName" value="" />
    <br>
    <br> Password:<br>
    <input type="password" name="password" value="" />
    <input value="Login" name="submit" type="submit" />
</form:form>

выход.jsp:

<a href="${pageContext.request.contextPath}/login.htm">Login</a>

Это работает просто отлично, единственная проблема заключается в том, что когда я выхожу из системы, ничего не происходит, у меня все еще есть разрешение, которое у меня было после входа в систему. Обычно он должен вернуться на экран входа в систему, запрашивая у пользователя аутентификацию для доступа к этой странице. Что мне не хватает?

И еще одна проблема, которую я не мог понять. Когда я меняю в форме входа в систему:

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

to:

<form name='loginform' action="<c:url value='j_spring_security_check' />" method='POST'>

Я получаю сообщение об ошибке:

Статус HTTP 404 — /Dronomy_2.1/j_spring_security_check

Может кто-нибудь помочь мне?


person Drastaro    schedule 16.07.2015    source источник
comment
Вы не собираетесь /logout.htm при переходе по ссылке, вы практически никогда не выходите из системы. Для вашего свойства login-processing-url установлено значение /login, поэтому при отправке формы вам нужно отправить ее на /login .   -  person M. Deinum    schedule 16.07.2015


Ответы (3)


Что касается выхода из системы с включенным CSRF, два ключевых места в вашем коде для этого:

logout-url="/logout.htm"

и

@RequestMapping(value = "/logout.htm", method = RequestMethod.GET)

Я предполагаю, что вам не нужно самостоятельно предоставлять страницу выхода. Чтобы выполнить выход, вам нужно, чтобы браузер пользователя выполнил POST для /logout.htm. В этот POST вам нужно включить ваши значения csrf. Этот POST относится к конечной точке безопасности spring, которую вы настроили с помощью logout-url="/logout.htm", а не выхода из системы в вашем контроллере.

Документация документация Spring предоставляет несколько вариантов того, как вы можете это сделать. Один из них — включить форму на все страницы, с которых ваш пользователь может выйти, и отправить форму с помощью Javascript, когда пользователь щелкнет ссылку меню выхода.

Если вы сделаете это, вы можете удалить сопоставление запросов, указанное выше.

person geoff.weatherall    schedule 18.07.2015

Я только что изменил файл security.xml в

<http use-expressions="true" disable-url-rewriting="true">
    <intercept-url pattern="/listUsers.htm" access="hasRole('ROLE_ADMIN')" />
    <intercept-url pattern="/play.htm" access="hasRole('ROLE_USER')" />
    <form-login login-page="/login.htm" login-processing-url="/j_spring_security_check"
        username-parameter="userName" password-parameter="password"
        default-target-url="/index.htm" always-use-default-target="true"
        authentication-failure-url="/login.htm?auth=fail" />
    <logout logout-url="/logout.htm" logout-success-url="/login.htm" />
</http>

добавлен

</c:if>
                <form method="post"
                    action="<c:url value='j_spring_security_check' />">

и убрано перенаправление на выход из контроллера. Теперь работает нормально, ти :)

person Drastaro    schedule 18.07.2015

Это работает просто отлично, единственная проблема в том, что когда я выхожу из системы, ничего не происходит.

Вы просто направляете пользователя на страницу входа. Сессия не считается недействительной. Объект SecurityContext не очищается.

Вам нужно использовать spring security /j_spring_security_logout для выхода пользователя из системы.

<a href="/j_spring_security_logout">LogOut</a>

Ознакомьтесь с этим примером

для вашей формы входа попробуйте

<form name='loginform' action="<c:url value='/j_spring_security_check' />" method='POST'>

Ошибка 404 обычно возникает из-за вычисления контекстного пути.

person underdog    schedule 16.07.2015
comment
И да и нет. Он перенастроил URL-адреса, чтобы URL-адреса по умолчанию больше не применялись. - person M. Deinum; 16.07.2015
comment
Ну, Deinum, я смутно помню проблему, возникшую с моим кодом, исправлением был контекстный путь, поэтому просто написал в ответе :) - person underdog; 16.07.2015
comment
я понимаю. но я использую форму ur, я получаю ошибку токена csrf: Статус HTTP 403 - Ожидаемый токен CSRF не найден. Срок вашей сессии истек? И когда я нажимаю кнопку выхода, я получаю только эту ссылку: localhost:8080/j_spring_security_logout - person Drastaro; 16.07.2015