2012-12-17 115 views
4

我是Spring Framework的初學者。我和我的朋友正在寫關於波茲南理工大學的工程師論文,我們在Spring Security(3.1.0)方面遇到了問題。我不能很好地註銷。當我想再次登錄時,我看到消息「用戶已經登錄」(我覆蓋了標準的Spring Security錯誤信息)。我試圖清除SecurityContextHolder的上下文,但它仍然不起作用。Spring Security - 無法註銷

彈簧的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>` 

的web.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> 

Controller.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); 
} 

}

我試圖修復它,我一直在尋找很長一段時間,但我不能找到解決辦法。

我希望你能幫助我。

Mateusz Jarmuzek, 盧卡斯Grzybowski

編輯: 我推翻標準Spring Security的錯誤消息。

更改後的代碼。

Controller.java

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


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

dummy.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> 

回答

4

這問題沒有在JSP中的重定向,但在設置。

試試這個:

web.xml中添加

<listener> 
<listener-class> 
org.springframework.security.web.session.HttpSessionEventPublisher 
</listener-class> 
</listener> 
+0

謝謝你的回答! – matjar

2

春季安全日誌出局的標準如下:

SecurityContextHolder.clearContext(); 

編輯

如果你正在使用JSP重定向,需要採取什麼是你需要一個空的JSP,做以下的事情:

1)使會話失效
2)重定向到着陸頁面

當我說空的時候,我的意思是它裏面唯一的內容是一個scriptlet,它完成了上面的兩部分。這樣的過程將如下所示:

1)用戶按下注銷
2)重定向到所述虛擬頁面作爲 如上所述發生
3)虛擬頁面對其執行代碼
4)用戶 現在從系統中註銷。

JSP代碼

<html> 
    <%session.invalidate()%>  
    //redirect logic 
</html> 
+0

謝謝,但它不工作。 – matjar

+0

@ user1910842你可以提供更多細節,以瞭解它如何不起作用?你也使用jsp重定向嗎? – Woot4Moo

+0

是的,我使用重定向。像Controller.java中的logout()方法一樣,「return」redirect:/ j_spring_security_logout「;」如果我理解你的話。 – matjar