5

Spring Security で保護された Stormpath Spring アプリケーションを作成したい開発者がライブラリとして使用する Spring Security 構成を作成しています。

そのためにWebSecurityConfigurerAdapter、Stormpath Access Controls とconfigure(HttpSecurity)を使用して StormpathAuthenticationProviderをサブクラス化し、定義しましたconfigure(AuthenticationManagerBuilder)。これはすべて、この抽象クラスとその具象サブクラスで確認できます。

@Order(99)
public abstract class AbstractStormpathWebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    //Removed properties and beans for the sake of keeping focus on the important stuff

    /**
     * The pre-defined Stormpath access control settings are defined here.
     *
     * @param http the {@link HttpSecurity} to be modified
     * @throws Exception if an error occurs
     */
    protected void configure(HttpSecurity http, AuthenticationSuccessHandler successHandler, LogoutHandler logoutHandler)
            throws Exception {

        if (loginEnabled) {
            http
                    .formLogin()
                    .loginPage(loginUri)
                    .defaultSuccessUrl(loginNextUri)
                    .successHandler(successHandler)
                    .usernameParameter("login")
                    .passwordParameter("password");
        }

        if (logoutEnabled) {
            http
                    .logout()
                    .invalidateHttpSession(true)
                    .logoutUrl(logoutUri)
                    .logoutSuccessUrl(logoutNextUri)
                    .addLogoutHandler(logoutHandler);

        }

        if (!csrfProtectionEnabled) {
            http.csrf().disable();
        } else {
            //Let's configure HttpSessionCsrfTokenRepository to play nicely with our Controllers' forms
            http.csrf().csrfTokenRepository(stormpathCsrfTokenRepository());
        }
    }

    /**
     * Method to specify the {@link AuthenticationProvider} that Spring Security will use when processing authentications.
     *
     * @param auth the {@link AuthenticationManagerBuilder} to use
     * @param authenticationProvider the {@link AuthenticationProvider} to whom Spring Security will delegate authentication attempts
     * @throws Exception if an error occurs
     */
    protected void configure(AuthenticationManagerBuilder auth, AuthenticationProvider authenticationProvider) throws Exception {
        auth.authenticationProvider(authenticationProvider);
    }
}

@Configuration
public class StormpathWebSecurityConfiguration extends AbstractStormpathWebSecurityConfiguration {

    //Removed beans for the sake of keeping focus on the important stuff

    @Override
    protected final void configure(HttpSecurity http) throws Exception {
        configure(http, stormpathAuthenticationSuccessHandler(), stormpathLogoutHandler());
    }

    @Override
    protected final void configure(AuthenticationManagerBuilder auth) throws Exception {
        configure(auth, super.stormpathAuthenticationProvider);
    }
}

要するに、基本的にログインとログアウトのメカニズムを定義し、CSRF コードを統合して Spring Security のコードとうまく連携させます。

この時点まで、すべて正常に動作します。

しかし、これは単なる「ライブラリ」であり、ユーザーにはその上に独自のアプリケーションを構築してもらいたいと考えています。

そのため、ユーザーがライブラリをどのように使用するかを示すサンプル アプリケーションを作成しました。

基本的に、ユーザーは独自のWebSecurityConfigurerAdapter. このような:

@EnableStormpathWebSecurity
@Configuration
@ComponentScan
@PropertySource("classpath:application.properties")
@Order(1)
public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {

    /**
     * {@inheritDoc}
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/restricted").fullyAuthenticated();
    }

}

これが実際に必要な場合は、WebApplicationInitializer次のようになります。

public class WebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext sc) throws ServletException {

        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(SpringSecurityWebAppConfig.class);
        context.register(StormpathMethodSecurityConfiguration.class);
        sc.addListener(new ContextLoaderListener(context));

        ServletRegistration.Dynamic dispatcher = sc.addServlet("dispatcher", new DispatcherServlet(context));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        //Stormpath Filter
        FilterRegistration.Dynamic filter = sc.addFilter("stormpathFilter", new DelegatingFilterProxy());
        EnumSet<DispatcherType> types =
                EnumSet.of(DispatcherType.ERROR, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST);
        filter.addMappingForUrlPatterns(types, false, "/*");

        //Spring Security Filter
        FilterRegistration.Dynamic securityFilter = sc.addFilter(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME, DelegatingFilterProxy.class);
        securityFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
    }
}

このコードはすべて正しく起動します。に行くとlocalhost:8080、ようこそ画面が表示されます。に行くとlocalhost:8080/login、ログイン画面が表示されます。しかし、localhost:8080/restricted次の行があるため、ログイン ページにリダイレクトされるはずですhttp.authorizeRequests().antMatchers("/restricted").fullyAuthenticated();。ただし、Access Denied代わりにページが表示されます。

次に、アプリのアクセス制御にログイン URL を追加すると、次のようになります。

protected void configure(HttpSecurity http) throws Exception {
    http
            .formLogin().loginPage("/login")
            .and()
            .authorizeRequests().antMatchers("/restricted").fullyAuthenticated();
}

ログインページにリダイレクトされますが、資格情報を送信するとすぐに、すべての構成が実際にはこのフィルターチェーンの一部ではないことを意味する CSRF 問題が発生します。

すべてをデバッグすると、それぞれWebApplicationInitializerが独自のフィルター チェーンを持つ独自のインスタンスを持っているようです。私はそれらが何らかの形で連結されることを期待していますが、実際には起こっていないようです...

誰もこのようなことを試したことがありますか?

public class SpringSecurityWebAppConfig extends StormpathWebSecurityConfigurationところで: の代わりにユーザーが実行できる回避策としてSpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter。このように機能しますが、ユーザーには純粋なSpring Securityコードを持たせStormpathWebSecurityConfiguration、その目標から逸脱して拡張したいと考えています。

すべてのコードはここで見ることができます。Spring 用の Stormpath Spring Security ライブラリは にありextensions/spring/stormpath-spring-security-webmvcます。ライブラリを使用した Sample App は の下にありexamples/spring-security-webmvcます。

実行するのは非常に簡単です...ここで説明されているように、Stormpath に登録するだけです。次に、spring_security_extension_redirect_to_login_not_workingブランチをチェックアウトして、次のようにサンプル アプリを起動できます。

$ git clone git@github.com:mrioan/stormpath-sdk-java.git
$ git checkout spring_security_extension_redirect_to_login_not_working
$ mvn install -DskipTests=true
$ cd examples/spring-security-webmvc
$ mvn jetty:run

次に、に移動しlocalhost:8080/restrictedて、ログイン ページにリダイレクトされていないことを確認できます。

どんな助けでも大歓迎です!

4

2 に答える 2

3

私の経験では、複数WebSecurityConfigurerの が起動時にセキュリティ構成を台無しにするという問題があります。

これを解決する最善の方法は、ライブラリ構成をSecurityConfigurerAdapters適切な場所に適用できるようにすることです。

public class StormpathHttpSecurityConfigurer
        extends AbstractStormpathWebSecurityConfiguration
        implements SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> {

    //Removed beans for the sake of keeping focus on the important stuff

    @Override
    protected final void configure(HttpSecurity http) throws Exception {
        configure(http, stormpathAuthenticationSuccessHandler(), stormpathLogoutHandler());
    }
}

public class StormpathAuthenticationManagerConfigurer
        extends AbstractStormpathWebSecurityConfiguration
        implements SecurityConfigurer<AuthenticationManager, AuthenticationManagerBuilder> {

    //Removed beans for the sake of keeping focus on the important stuff

    @Override
    protected final void configure(AuthenticationManagerBuilder auth) throws Exception {
        configure(auth, super.stormpathAuthenticationProvider);
    }
}

次に、ユーザーapplyにこれらを独自の構成で提供します。

@EnableStormpathWebSecurity
@Configuration
@ComponentScan
@PropertySource("classpath:application.properties")
@Order(1)
public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/restricted").fullyAuthenticated()
                .and()
            .apply(new StormPathHttpSecurityConfigurer(...))
        ;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.apply(new StormPathAuthenticationManagerConfigurer(...));
    }
}
于 2016-10-04T07:56:39.857 に答える