2012-12-17 113 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