6

ユーザーがログアウトするときに、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 は削除されるのではなく、複製されるだけです。

古いクッキー

新しいクッキー

そのため、ブラウザを「/timeout」URL にリダイレクトし続けます。

Chrome Web ブラウザーの開発者ツールを使用して何が起こっているのかを追跡しようとしたところ、この Cookie が次の応答ヘッダーで設定されていることがわかりました。

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

そして、この応答ヘッダーで削除します:

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

よくわかりませんが、理由はこれらのヘッダーの「パス」フィールドにあるようです。最初のヘッダーでは「/website/」を指し、2 番目のヘッダーでは「/website」を指しています。

記載されているトラブルの理由でしょうか?それが理由ではない場合 (または唯一の理由ではない場合)、他の理由は何ですか? この問題を解決するにはどうすればよいですか?

4

5 に答える 5

8

JSESSIONIDこのように明示的に Cookie を削除する必要はありません。Spring Security 自体ではなく、サーブレット コンテナーによって管理されます。Spring Security はデフォルトで、ログアウト時に http セッションを無効にします。これにより、サーブレット コンテナーがJSESSIONIDCookie を削除します。

于 2013-04-11T10:18:38.723 に答える
5

私の場合、 SecurityContextLogoutHandlerがsession.invalidate() を呼び出しても、何らかの理由でJSESSIONIDクリアされません。その値は同じままでした。

OPが試したのと同じ方法を使用しようとしましdelete-cookies="JSESSIONID"たが、同じ問題があったと思います.Cookieに設定されたパスは/、最後にaのないコンテキストパスだったので、まだクリアされません(注文を出していました)存在しない Cookie を削除します)。

Cookie のコンテキスト パスを設定する行を除いて、CookieClearingLogoutHandlerProperCookieClearLogoutHandler同じです。

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

次に、この方法でLogoutFilterの構成を設定します。spring-security.xml

    <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>
于 2015-09-17T11:21:16.477 に答える
2

これは私がセッションを無効にする方法です:

<security:logout invalidate-session="true" logout-success-url="/myapp/auth/login" logout-url="/myapp/auth/logout" />
于 2013-04-13T06:09:20.927 に答える
2

spring が提供するデフォルトの CookieClearingLogoutHandler は、Cookie パスの違いにより JSESSIONID をクリアできませんでした。

Cookie のパスは変更しないでください。これにより、Cookie ID が変更されます。Cookie が /foo のようなパスに設定されていて、これを / に変更すると、クライアントは変更された Cookie を元の Cookie に関連付けなくなります。Cookie は、名前とパスによって識別されます。

したがって、上記のソリューション、つまり (ProperCookieClearingLogoutHandler.class) に示すようにカスタム 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);

        }

    }
于 2016-03-16T05:20:07.160 に答える
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() {}
}
于 2015-01-29T07:20:12.073 に答える