9

私はSpring Boot 1.2.3 Webアプリケーション内でSpring Security 4.0.1を使用しています(また、Spring-session 1.0.1でも使用していますが、これはケースには関係ありません)。

プライベート エリアと、すべてのユーザーがアクセスできるすべてのアクセス エリア ("/about"、"/"、"/contact"、... 20 ページ以上) があります。(ウェブショップのようなものです)

ログインしたユーザー セッションの有効期限が切れるたびに、Spring は無効なセッションを検出し、ユーザーを「.invalidSessionUrl("/session/error/invalid")」にリダイレクトします。

ただし、ターゲット リンクがプライベート エリア内またはパブリック エリア内にある場合にのみ、リダイレクトしたいと考えています。

どうすればそれを回避できますか?

ありがとう。

これは私の(Java)設定です:(投稿を見た後に更新)

 http
            .authorizeRequests()
            .anyRequest()
                .permitAll()
            .antMatchers("/privado/**")
                .authenticated()
            .and()
                .formLogin()
                .loginPage("/login")
                .failureUrl("/login?error")
                .defaultSuccessUrl("/")
                .successHandler(new SessionSuccessHandler())
            .and()
                .logout()
                .logoutSuccessUrl("/")
                .deleteCookies("JSESSIONID", "SESSION")
            .and()
                .sessionManagement()
                .invalidSessionUrl("/session/error/invalid")
            .sessionFixation()
            .changeSessionId()
            .maximumSessions(1)
            .expiredUrl("/session/error/expired")
            .and()
            .and()
                .csrf()
                .ignoringAntMatchers("/jolokia/**", "/v1.0/**");

どうすればそれを達成できますか?

どうもありがとう。

4

3 に答える 3

2

@RobWinch - これはかなり一般的なユースケースのようで、提案したソリューションは、私が実行したテストとコメントからは機能しないようです。同様の問題が提起されましたhttp://forum.spring.io/forum/spring-projects/security/94772-redirect-to-invalid-session-url-only-when-user-accesses-secured-resourceとそれ解決されていないようです。私の考えは、複数のhttp設定を持つことです(xml構成を使用)

<http pattern="/aboutUs**" security="none" />
<http pattern="/contact**" security="none" />
etc

保護されていないページが多数あり、新しい保護されていないページを追加するために構成の更新が必要な場合、これは理想的ではないようです。このユースケースに「理想的な」ソリューションがあればいいのですが。Spring security 4.1 リリースでは、これを行う明確な方法がまだないようです。

于 2016-08-18T01:27:45.573 に答える
2

あなたと同様の状況でこの問題に対処するのに役立った別の回避策は、次のように構成に期限切れ/無効なセッション戦略を追加することです。

http
    .expiredSessionStrategy(e -> {
        handleExpiredInvalidSessions(e.getRequest(), e.getResponse());
    })
    .sessionRegistry(sessionRegistry())
    .and()
    .invalidSessionStrategy((request, response) -> {
        handleExpiredInvalidSessions(request, response);
    })

次に、パブリック URI に一致するように実装し、単純にリクエストを転送します。

private void handleExpiredInvalidSessions(HttpServletRequest request, HttpServletResponse response) {
    String requestUri = request.getRequestURI();
    if (isPublicURI(requestUri)) {
        // This will remove the invalid/expired session from the request
        // and prevent the request from failing again
        request.getSession(true).invalidate();
        RequestDispatcher dispatcher = request.getRequestDispatcher(requestUri);
        // Retry the request
        dispatcher.forward(request, response);
    } else {
        // might redirect if you wish
        response.setStatus(440);
    }
}

目的のパブリック パスに応じて実装する必要がありisPublicURI()ますが、私の場合はパスが 1 つだけだったので、非常に簡単でした。

于 2019-11-29T14:20:26.000 に答える
0

これを行うために、カスタム SessionAuthenticationStrategy を提供できます。例えば:

public class MatcherSessionAuthenticationStrategy implements SessionAuthenticationStrategy {

    private final SessionAuthenticationStrategy delegate;

    private final RequestMatcher matcher;

    public MatcherSessionAuthenticationStrategy(
            SessionAuthenticationStrategy delegate, RequestMatcher matcher) {
        super();
        this.delegate = delegate;
        this.matcher = matcher;
    }

    public void onAuthentication(Authentication authentication,
            HttpServletRequest request, HttpServletResponse response)
            throws SessionAuthenticationException {
        if(matcher.matches(request)) {
            delegate.onAuthentication(authentication, request, response);
        }
    }
}

次に、RequestMatcher と ConcurrentSessionControlAuthenticationStrategy をクラスに挿入できます。これを構成する最も簡単な方法は、BeanPostProcessor を作成することです。

public class ConcurrentSessionControlAuthenticationStrategyBeanPostProcessor
        implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        if(!(bean instanceof CompositeSessionAuthenticationStrategy)) {
            return bean;
        }

        RequestMatcher matcher = antMatchers("/about", "/","/contact");
        SessionAuthenticationStrategy original = (SessionAuthenticationStrategy) bean;
        return new MatcherSessionAuthenticationStrategy(original, matcher);
    }

    /**
     * Create a {@link List} of {@link AntPathRequestMatcher} instances.
     *
     * @param httpMethod the {@link HttpMethod} to use or {@code null} for any
     * {@link HttpMethod}.
     * @param antPatterns the ant patterns to create {@link AntPathRequestMatcher}
     * from
     *
     * @return an OrRequestMatcher with a {@link List} of {@link AntPathRequestMatcher} instances
     */
    public static RequestMatcher antMatchers(
            String... antPatterns) {
        List<RequestMatcher> matchers = new ArrayList<RequestMatcher>();
        for (String pattern : antPatterns) {
            matchers.add(new AntPathRequestMatcher(pattern));
        }
        return new OrRequestMatcher(matchers);
    }
}

その後、構成に以下を追加できます。

@Bean
public static BeanPostProcessor sessionBeanPostProcessor() {
    return new ConcurrentSessionControlAuthenticationStrategyBeanPostProcessor();
}

これは早い段階で初期化する必要がある BeanPostProcessor であるため、静的メソッドを使用することが重要です。

PSこのブログで概説されているように、構成をフォーマットすることを検討します

于 2015-06-17T21:24:19.933 に答える