我需要在用户注销时删除cookie JSESSIONID。 为此,我将以下配置添加到我的安全配置中:

<http>
    <form-login login-page="/login*" authentication-failure-url="/login?try_again" />
    <http-basic />
    <logout logout-url="/logout" delete-cookies="JSESSIONID" />
    <session-management invalid-session-url="/timeout" />

    <intercept-url pattern="/login*"    access="IS_AUTHENTICATED_ANONYMOUSLY" />

    ...

</http>

但是,cookie不会被删除,而是变得重复:

老饼干

新的cookie

所以它一直将浏览器重定向到“/ timeout”URL。

我尝试使用Chrome网络浏览器中的开发人员工具跟踪正在发生的事情,我发现此Cookie设置了此响应标头:

Set-Cookie:JSESSIONID=CFF85EA743724F23FDA0317A75CFAD44; Path=/website/; HttpOnly

并使用此响应标头删除:

Set-Cookie:JSESSIONID=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/website

我不确定,但似乎原因在于这些标题的“路径”字段:在第一个中它指向“/ website /”,在第二个中它指向“/ website”。

这是所描述的麻烦的原因吗? 如果不是原因(或不是唯一原因),那么其他原因是什么? 我该如何解决这个问题呢?

#1楼 票数:6 已采纳

您不需要像这样显式删除JSESSIONID cookie。 它不是由Spring Security管理的,而是由您的servlet容器管理的。 默认情况下,Spring Security将在注销时使http会话无效,这反过来会导致您的servlet容器删除JSESSIONID cookie。

#2楼 票数:3

在我的情况下出于某种原因,即使SecurityContextLogoutHandler调用session.invalidate(),也不会清除JSESSIONID 它的价值保持不变。

我试着像OP尝试的那样使用delete-cookies="JSESSIONID" ,我相信我遇到了同样的问题:为cookie设置的路径是没有/最后的上下文路径,所以它仍然不会被清除(它是命令删除不存在的cookie)。

我最终编写了自己的ProperCookieClearLogoutHandler ,它与CookieClearLogoutHandler相同,除了设置cookie的上下文路径的行:

package com.testdomain.testpackage;

import java.util.Arrays;
import java.util.List;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

public final class ProperCookieClearingLogoutHandler implements LogoutHandler {
    private final List<String> cookiesToClear;

    public ProperCookieClearingLogoutHandler(String... cookiesToClear) {
        Assert.notNull(cookiesToClear, "List of cookies cannot be null");
        this.cookiesToClear = Arrays.asList(cookiesToClear);
    }

    public void logout(HttpServletRequest request, HttpServletResponse response,
            Authentication authentication) {
        for (String cookieName : cookiesToClear) {
            Cookie cookie = new Cookie(cookieName, null);
            String cookiePath = request.getContextPath() + "/";
            if (!StringUtils.hasLength(cookiePath)) {
                cookiePath = "/";
            }
            cookie.setPath(cookiePath);
            cookie.setMaxAge(0);
            response.addCookie(cookie);
        }
    }
}

然后我以这种方式在spring-security.xml上设置LogoutFilter的配置;

    <bean id="logoutFilter"
        class="org.springframework.security.web.authentication.logout.LogoutFilter">
        <constructor-arg name="logoutSuccessUrl" value="/views/login/login.xhtml?logout" />
        <constructor-arg>
            <list>
                <bean id="properCookieClearingLogoutHandler"
                    class="com.imatia.arpad.gplenos.authorization.ProperCookieClearingLogoutHandler">
                    <constructor-arg name="cookiesToClear">
                        <list>
                            <value>JSESSIONID</value>
                        </list>
                    </constructor-arg>
                </bean>
                <bean id="securityContextLogoutHandler"
                    class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
                </bean>
            </list>
        </constructor-arg>
        <property name="filterProcessesUrl" value="/logout" />
    </bean>

#3楼 票数:2

这就是我使会话无效的方式:

<security:logout invalidate-session="true" logout-success-url="/myapp/auth/login" logout-url="/myapp/auth/logout" />

#4楼 票数:1

由于cookie路径不同,spring提供的默认CookieClearingLogoutHandler无法清除JSESSIONID。

你不应该改变cookie的路径。 这会改变cookie身份。 如果为/ foo这样的路径设置了cookie并将其更改为/,则客户端将不再将更改的cookie与原始cookie相关联。 Cookie由名称和路径标识。

因此,您需要实现一个自定义CookieClearingLogoutHandler,如上面的解决方案所示(即ProperCookieClearingLogoutHandler.class),并将其设置为spring security,如下面的代码所示。而不是使用.deleteCookies(“JSESSIONID”,“USER”),它添加了CookieClearingLogoutHandler默认。

Spring Security Java配置:

@Configuration
@EnableWebSecurity
@ComponentScan(basePackages = "com.dentist.webapp")
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private SessionRegistry sessionRegistry;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/resources/**", "/signup/*", "/about", "/login/*").permitAll().anyRequest()
                .authenticated()
                .and().formLogin()
                                 .loginPage("/login/form")
                                 .permitAll()
                .and().logout()
                              .invalidateHttpSession(true)
                              .clearAuthentication(true)
                             // .deleteCookies("JSESSIONID","USER")
                              .addLogoutHandler(new ProperCookieClearingLogoutHandler("JSESSIONID","USER"))
                              .permitAll()
                .and().sessionManagement()
                              .maximumSessions(1)
                              .maxSessionsPreventsLogin(true)
                              .expiredUrl("/accessDenied")
                              .sessionRegistry(sessionRegistry);

        }

    }

#5楼 票数:0

如何在注销时删除很简单:您实现注销并将该代码放在方法中:

    HttpSession session = request.getSession(false); 
    if (session != null) { 
       session.invalidate();
    }

无效会话将使cookie无效。

但我尝试并发现,当我关闭浏览器而没有注销时,JSESSIONID cookie会在打开浏览器时幸存并且用户可以进入系统。

为了消除这种情况,我创建了一个过滤器,它也会在登录时使会话无效,创建一个新的会话,您的登录将从开始执行。

@WebFilter(urlPatterns = {"/login/*"}, description = "sessionKiller", filterName="sessionKiller")
public class SessionKillerFilter implements Filter{

    @Override
    public void init(FilterConfig arg0) throws ServletException {}

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
        //kill older session and create new one on explicit login
        //this is to prevent user to login 2-ce
        //also this is prevention of re-connect on cookie base, when browser closed and then open
        HttpServletRequest  request = (HttpServletRequest)req;
        HttpSession session =   request.getSession(false);
        if(session!=null){
            session.invalidate();//old session invalidated
        }
        request.getSession(true);//new session created

        chain.doFilter(req, resp);
    }

    @Override
    public void destroy() {}
}

  ask by user1764823 translate from so

未解决问题?本站智能推荐:

1回复

Spring Security无法使用Nginx服务器创建JSESSION ID

我已经在spring mvc应用程序中实现了spring security,它对我来说很好用,但是我现在尝试使用Nginx服务器配置访问此应用程序。Spring Security在最后停止工作。我发现spring security无法创建JSESSIONID cookie。 Nginx服务器。
1回复

无法登录Spring Security

在实现基于注释的Spring Security时,我一直遇到问题。 当我从我的有角度的UI中发布数据时,它会到达Spring Security,但是,它根本不会进入登录尝试。 我不知道我在哪里做错了。 我的无状态登录过滤器是: 我的春季安全配置文件是: 当我启动服务
2回复

为什么Spring Security无法运行?

我正在尝试将Spring Security集成到我的项目中。 我按照这里给出的文档: https : //spring.io/guides/gs/securing-web/ 我使用XML配置了所有内容,而不是Spring Boot。 我的web.xml是: <liste
1回复

无法使用Spring Security登录

我正在尝试自定义在现有spring mvc应用程序中实现的spring security Login机制。 这是Spring Security xml文件中的条目 这工作得很好,因为每当用户要登录时,他/她都被重定向到具有类似URL的登录页面 根据新要求,我们必须在整个应用程序
1回复

Spring Security无法登录

这是我的春季安全配置的摘录: 当我输入登录表单admin admin时,我将重定向到authentication-failure-url。 我究竟做错了什么? 我正在使用Spring Security版本3.2.0.RELEASE。 在此先感谢您的帮助。 最好的祝福
1回复

Spring Security无法识别我自己的权限

我正在尝试使用自己的permissionEvaluator , 但看起来像spring无法识别我的设置。 到目前为止,我做到了: web.xml spring-security.xml spring-security.xml spring-securit
2回复

为什么我的Spring Security无法正常工作?

我目前正在做一个关于Spring MVC的项目,我正在尝试整合Spring Security。 但是我没有这样做,我完全不知道我缺少什么。 请查看我的代码并提供您的建议。 <?xml version="1.0" encoding="UTF-8"?> <beans xmln
1回复

Spring Security无法解析XML

我有一个问题,我不能使用spring mvc 3.2.4和spring security 3.1.4。 他们抛出了一个例外,他们无法解析spring-security.xml。 这是我的示例代码: 控制器: web.xml中 弹簧security.xml文件: