web-dev-qa-db-ja.com

Spring Securityでセッションを有効にしてセッションタイムアウトを設定する方法

私はSpring Securityの初心者であり、ログイン、ログアウト、およびセッションタイムアウト機能に取り組んでいます。 this documentを参照してコードを構成しました。私のコードは以下のようになります:

@Override
protected void configure(HttpSecurity http) throws Exception {

    http.authorizeRequests().antMatchers("/admin/**")
        .access("hasRole('ROLE_USER')").and().formLogin()
        .loginPage("/login").failureUrl("/login?error")
            .usernameParameter("username")
            .passwordParameter("password")
            .and().logout().logoutSuccessUrl("/login?logout").and().csrf();
    http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired");
}

クラスAbstractSecurityWebApplicationInitializerをオーバーライドします

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {

    @Override
    public boolean enableHttpSessionEventPublisher() {
        return true;
    }

}

私はそれが正しく行われているかどうか、それがよさそうであれば、そしてセッションタイムアウトを設定する必要がある場所を明確にする必要があります。私は完全に注釈に基づいてそれをやっています。

22
raju vaishnav

Web.xmlのみに以下の設定を追加することで、上記の問題を解決できました。より良い方法が受け入れられます。

 <session-config>
    <session-timeout>20</session-timeout>
</session-config>
13
raju vaishnav

JavaConfig を使用していて、XMLを使用したくない場合は、HttpSessionListenerを作成してgetSession().setMaxInactiveInterval()を使用し、InitializeronStartup()のリスナー:

public class SessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent event) {
        System.out.println("session created");
        event.getSession().setMaxInactiveInterval(15);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent event) {
       System.out.println("session destroyed");
    }
}

次に、イニシャライザで:

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    super.onStartup(servletContext);
    servletContext.addListener(new SessionListener());
}
24
munilvc

Application.properties set property server.session.timeout=値を使用する場合、値は秒単位です。

8
JJ Roman

Spring Securityでセッションタイムアウト時間(maxInactiveInterval)を構成するさまざまな方法。

1. web.xmlにセッション構成を追加する(raju vaishnavの回答より)

2. HttpSessionListenerの実装を作成し、サーブレットコンテキストに追加する(munilvcの答えから)

3.カスタムSecuritySuccessHandlerをスプリングセキュリティ構成に登録し、onAuthenticationSuccessメソッドでセッションの最大非アクティブ間隔を設定する。

この実装には利点があります

  1. ログインが成功すると、異なるロール/ユーザーに対して異なる値maxInactiveIntervalを設定できます。

  2. ログインに成功すると、セッションでユーザーオブジェクトを設定できるため、セッションから任意のコントローラーでユーザーオブジェクトにアクセスできます。

短所:ANONYMOUSユーザー(非認証ユーザー)にセッションタイムアウトを設定できません

AuthenticationSuccessHandlerハンドラーを作成する

public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler
{

    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
            throws IOException 
    {
        Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
        if (roles.contains("ROLE_ADMIN"))
        {
            request.getSession(false).setMaxInactiveInterval(60);
        }
        else
        {
            request.getSession(false).setMaxInactiveInterval(120);
        }
        //Your login success url goes here, currently login success url="/"
        response.sendRedirect(request.getContextPath());
    }
}

成功ハンドラーを登録する

In Java Config way

@Override
protected void configure(final HttpSecurity http) throws Exception
{
    http
        .authorizeRequests()
            .antMatchers("/resources/**", "/login"").permitAll()
            .antMatchers("/app/admin/*").hasRole("ADMIN")
            .antMatchers("/app/user/*", "/").hasAnyRole("ADMIN", "USER")
        .and().exceptionHandling().accessDeniedPage("/403")
        .and().formLogin()
            .loginPage("/login").usernameParameter("userName")
            .passwordParameter("password")
            .successHandler(new MyAuthenticationSuccessHandler())
            .failureUrl("/login?error=true")
        .and().logout()
            .logoutSuccessHandler(new CustomLogoutSuccessHandler())
            .invalidateHttpSession(true)
        .and().csrf().disable();

    http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired=true");
}

Xml構成の方法で

<http auto-config="true" use-expressions="true" create-session="ifRequired">
    <csrf disabled="true"/>

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

    <intercept-url pattern="/app/admin/*" access="hasRole('ROLE_ADMIN')" />
    <intercept-url pattern="/" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />
    <intercept-url pattern="/app/user/*" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />

    <access-denied-handler error-page="/403" />

    <form-login 
        login-page="/login"
        authentication-success-handler-ref="authenticationSuccessHandler"
        authentication-failure-url="/login?error=true" 
        username-parameter="userName"
        password-parameter="password" />

    <logout invalidate-session="false" success-handler-ref="customLogoutSuccessHandler"/>

    <session-management invalid-session-url="/login?expired=true">
        <concurrency-control max-sessions="1" />
    </session-management>
 </http>

 <beans:bean id="authenticationSuccessHandler" class="com.pvn.mvctiles.configuration.MyAuthenticationSuccessHandler" />

作業コードは my github repository で使用できます。作業コードは2つの形式で使用できます

1。XML設定の実装方法

2。Java configの実装方法

セッションが期限切れになりそうなときに表示される自動ログアウト機能とタイマーが必要な場合、ユーザーがフォームに入力しているが送信されていない場合、ユーザーはセッションを維持するボタンをクリックしてセッションを延長できます。自動ログアウトを実装する場合は、 セッションタイムアウト時の自動ログアウト時のスタックオーバーフロー応答 を参照してください。これが役立つことを願っています。