0

私はSpring 4に1つのアプリケーションを持っています.Spring Securityを認証に使用し、Spring Sessionを使用してクラスター化された環境でセッションを共有します。

私はSpring SessionからsessionRepositoryを実装してセッションをデータベースに保存していたので、サイトの春のセッションに入ると「SESSION」という名前のCookieを作成してDBに保存します。

このセッション DB 実装のアイデアは次のとおりです。

Spring 4 でリレーショナル データベース ベースの HTTP セッション パーシスタンスを行うにはどうすればよいですか?

現時点では、「SESSION」という 1 つの Cookie があります。サイトにログインすると、Spring Security は別の Cookie「JSESSION」を作成しますが、これは DB に保存されず、この Cookie には「認証情報」があります。

私の質問は次のとおりです。この実装は、クラスター化された環境に適していますか? または、別の変更を加える必要がありますか?

前もって感謝します。

編集2:

私は最近アプリをテストしましたが、説明を1つ間違えました。サイトにアクセスすると、「SESSION」Cookieにログインしても「SESSION」Cookieが1つ残っていますが、別のCookieはありません。セッション テーブルを更新し、ユーザーがログオフしているサイトを更新します。これは正しい動作ですか?

編集:

これが SecurityConfig からの「構成」です (WebSecurityConfigurerAdapter から拡張)。

@Override
protected void configure(final HttpSecurity http) throws Exception {
    // @formatter:off
    http
        //.csrf().disable()
        .authorizeRequests()
        .antMatchers(
                "/login*",
                "/logout*",
                "/forgotPassword*",
                "/user/initResetPassword*",
                "/user/resetPassword*",
                "/admin/saveConfiguration",
                "/resources/**"
        ).permitAll()
        .antMatchers("/invalidSession*").anonymous()
        .anyRequest().authenticated()
    .and()
        .formLogin()
        .loginPage("/login.html")
        .loginProcessingUrl("/login")
        .defaultSuccessUrl("/homepage.html")
        .failureUrl("/login.html?error=true")
        .successHandler(myAuthenticationSuccessHandler)
        .usernameParameter("username")
        .passwordParameter("password")
        .permitAll()
    .and()
        .addFilterBefore(this.sessionSessionRepositoryFilter, ChannelProcessingFilter.class)
        .sessionManagement()
        .invalidSessionUrl("/login.html")
        .sessionFixation()
        .migrateSession()
    .and()
        .logout()
        .invalidateHttpSession(false)
        .logoutUrl("/vu_logout")
        .logoutSuccessUrl("/logout.html?ls=true")
        .deleteCookies("JSESSION")
        .logoutSuccessHandler(mySimpleUrlLogoutSuccessHandler)
        .permitAll();
    // @formatter:on
}

ここで私のログイン成功ハンドラ:

@Component("myAuthenticationSuccessHandler")
public class MySimpleUrlAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private final Logger LOGGER = LoggerFactory.getLogger(getClass());

private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
    handle(request, response, authentication);
    HttpSession session = request.getSession(false);

    if (session != null) {
        session.setMaxInactiveInterval(60 * 10);
    }
    clearAuthenticationAttributes(request);
}

protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
    String targetUrl = determineTargetUrl(authentication);

    if (response.isCommitted()) {
        return;
    }

    redirectStrategy.sendRedirect(request, response, targetUrl);
}

protected String determineTargetUrl(Authentication authentication) {
    boolean isUser = false;
    boolean isAdmin = false;
    Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
    for (GrantedAuthority grantedAuthority : authorities) {
        if (grantedAuthority.getAuthority().equals("OPER") || grantedAuthority.getAuthority().equals("AUDITOR")) {
            isUser = true;
        } else if (grantedAuthority.getAuthority().equals("ADMIN")) {
            isAdmin = true;
            isUser = false;
            break;
        }
    }

    if(isUser || isAdmin)
    {
        return "/home.html";
    }
    else
    {
        throw new IllegalStateException();
    }
}

protected void clearAuthenticationAttributes(HttpServletRequest request) {
    HttpSession session = request.getSession(false);
    if (session == null) {
        return;
    }
    session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
}

public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
    this.redirectStrategy = redirectStrategy;
}

protected RedirectStrategy getRedirectStrategy() {
    return redirectStrategy;
}

}

4

1 に答える 1

0

数日間の調査とテストの後、この実装はクラスター化された環境で正しく動作するようになりました。

サンプル プロジェクトが必要な場合は、Mati が github リポジトリに 1 つ持っています: https://github.com/Mati20041/spring-session-jpa-repository

于 2015-11-27T20:16:47.937 に答える