Spring Security - невозможно выйти из системы

Я новичок в Spring Framework. Я и мой друг пишем нашу инженерную диссертацию в Познаньском технологическом университете, и у нас есть проблема с Spring Security (3.1.0). Я НЕ могу выйти из системы. Когда я хочу снова войти в систему, я вижу сообщение «Пользователь уже вошел в систему» ​​(я отменил стандартное сообщение об ошибке Spring Security). Я пытался очистить контекст SecurityContextHolder, но он все еще не работает.

весна-security.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:security="http://www.springframework.org/schema/security"
    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.1.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <security:http auto-config="true" create-session="ifRequired">
        <security:intercept-url pattern="/start"
            access="IS_AUTHENTICATED_ANONYMOUSLY" />
        <security:intercept-url pattern="/home" access="ROLE_USER" />       
        <security:session-management>
            <security:concurrency-control 
                max-sessions="1" error-if-maximum-exceeded="true" />
        </security:session-management>
        <security:form-login login-page="/start"
            default-target-url="/home" authentication-failure-url="/login_error?error=true"
            always-use-default-target="true" />
        <security:logout invalidate-session="true" logout-success-url="/start" logout-url="/j_spring_security_logout"/>
    </security:http>
    <security:authentication-manager>
        <security:authentication-provider ref="myAuthenticationProvider"/>
    </security:authentication-manager>


    <bean id="myAuthenticationProvider" name="myAuthenticationProvider" class="org.pp.web.Authentication.XtbAuthenticationProvider"/>
</beans>`

веб.xml

<!-- Spring Security -->
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>
                  org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>



    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

home.jsp

<a href="<c:url value="/logout" />">Logout</a>

Контроллер.java

@RequestMapping(value = "logout")
public String logout() {
    SecurityContextHolder.clearContext();
    return "redirect:/j_spring_security_logout";
}

@RequestMapping(value = "start")
public String start(Model model, HttpServletRequest request) {
    // sprawdzenie czy uzytkownik nie jest juz zalogowany
    if (request.getRemoteUser() == null) {

        return "start";
    } else {

        return "redirect:/home";
    }
}

У меня есть свой провайдер для проверки логина и пароля.

AuthProvider.java

public class AuthenticationProvider implements AuthenticationProvider{

private Logger logger = Logger.getLogger(AuthenticationProvider.class);

@Override
public Authentication authenticate(Authentication authentication)
        throws AuthenticationException {

    List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
    authorities.add(new GrantedAuthorityImpl("ROLE_USER"));

    UsernamePasswordAuthenticationToken auth = (UsernamePasswordAuthenticationToken) authentication;
    String username = String.valueOf(auth.getPrincipal());
    String password = String.valueOf(auth.getCredentials());

    if(username.length()<4)
    {
        logger.warn("Error: Login is to short for username: "+ username);
        throw new BadCredentialsException("Login is to short!");
    }
    else if(password.length()<4)
    {
        logger.warn("Error: Password is to short for username: "+ username);
        throw new BadCredentialsException("Password is to short!");

    }
    else if(!(  (username.equals("login") & password.equals("password"))|
            (username.equals("login2") & password.equals("password2"))) ) {
        logger.warn("Error: Incorrect data for username: "+ username);
        throw new BadCredentialsException("Incorrect data!");
    }

    return new UsernamePasswordAuthenticationToken(
        authentication.getName(), authentication.getCredentials(),
        authorities);
}

@Override
public boolean supports(Class<?> authentication) {
    return authentication.equals(UsernamePasswordAuthenticationToken.class);
}

}

Я пытался исправить это, и я искал долгое время, но я не могу найти решение.

Надеюсь, вы мне поможете.

Матеуш Ярмужек, Лукаш Гжибовски

Изменить: я отменил стандартное сообщение об ошибке Spring Security.

Код после изменений.

Контроллер.java

    @RequestMapping(value = "dummy")
public String dummy() {
    //SecurityContextHolder.clearContext();
    return "redirect:/dummy";
}


@RequestMapping(value = "logout")
public String logout() {
    //SecurityContextHolder.clearContext();
    return "redirect:/start";
}

манекен.jsp

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

<% 

session.invalidate(); 
// String redirectURL = "http://localhost:8080/start";
// response.sendRedirect(redirectURL);

%>

<body>
<%-- <c:redirect url='http://localhost:8080/start' /> --%>
</body>

</html>

home.jsp

<a href="<c:url value='/dummy' />">Logout</a>

person matjar    schedule 17.12.2012    source источник


Ответы (2)


Проблема не в переадресации JSP, а в настройках.

Попробуй это:

Добавить в web.xml

<listener> 
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class> 
</listener>
person Lukasz    schedule 18.12.2012

Стандарт выхода из системы безопасности Spring выглядит следующим образом:

SecurityContextHolder.clearContext();

ИЗМЕНИТЬ

Если вы используете перенаправления jsp, вам нужен пустой jsp, который выполняет следующие действия:

1) Делает сеанс недействительным
2) Перенаправляет на целевую страницу

Когда я говорю «пустой», я имею в виду, что единственное содержимое внутри него — это скриптлет, выполняющий две описанные выше части. Итак, процесс будет выглядеть следующим образом:

1) Пользователь нажимает кнопку "Выйти"
2) Происходит перенаправление на фиктивную страницу, как описано выше
3) Фиктивная страница выполняет свой код
4) Теперь пользователь вышел из системы.

КОД JSP

<html>  
    <%session.invalidate()%>    
    //redirect logic
</html>  
person Woot4Moo    schedule 17.12.2012
comment
Спасибо, но это не работает. - person matjar; 17.12.2012
comment
@user1910842 user1910842, можете ли вы рассказать подробнее, почему это не работает? Вы также используете перенаправления jsp? - person Woot4Moo; 17.12.2012
comment
Да, я использую редиректы. Как и в методе logout() в Controller.java return redirect:/j_spring_security_logout; Если я тебя хорошо понимаю. - person matjar; 17.12.2012
comment
@ user1910842 обновлен, чтобы объяснить обходной путь - person Woot4Moo; 17.12.2012
comment
большое спасибо, но у меня все еще есть проблема. Да, я использую перенаправления JSP. Что значит сделать сеанс недействительным? Это метод clearContext()? Я создал пустой jsp, но не знаю, какой код там выполняется. - person matjar; 18.12.2012
comment
@matjar Я опубликовал скриптлет, о котором говорил. - person Woot4Moo; 18.12.2012
comment
Это работает, но у меня HTTP 310 ERROR -> ERR_TOO_MANY_REDIRECTS. - person matjar; 18.12.2012
comment
@matjar Ну, может быть, убрать весеннее перенаправление безопасности? Я не уверен, он отлично работает в моей системе - person Woot4Moo; 18.12.2012
comment
Я обновил свой первый пост. - person matjar; 18.12.2012
comment
@ Woot4Moo Главная деталь в том, что сейчас весна, а весна просто отстой. 100500 способов сделать простой выход из системы, и ни один из них не работает! - person parsecer; 13.03.2020