web-dev-qa-db-ja.com

web.xmlなしのSpring Security

Web.xmlファイルの代わりにSpringの新しいWebApplicationInitializerインターフェイスを使用しているWebアプリケーションにSpring Securityを追加するための推奨される方法は何ですか?私は同等のものを探しています:

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

[〜#〜]更新[〜#〜]
提供された回答は合理的ですが、どちらもservletContextインスタンスがあることを前提としています。私はWebApplicationInitializersの階層を調べましたが、Springの初期化メソッドのいずれかをオーバーライドすることを選択しない限り、サーブレットコンテキストへのアクセスは表示されません。 AbstractDispatcherServletInitializer.registerServletFilterは賢明な選択のように見えますが、デフォルトではURLパターンマッピングに設定されていないため、より良い方法がある場合は、すべてのフィルター登録を変更するのは嫌です。

20
Jeff

これは私がそれをした方法です:

container.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain"))
                    .addMappingForUrlPatterns(null, false, "/*");

コンテナはServletContextのインスタンスです

26
Biju Kunjummen

Spring Security Reference がこの質問に回答します。解決策は、Spring SecurityをSpringまたはSpring MVCと組み合わせて使用​​しているかどうかによって異なります。

SpringまたはSpring MVCを使用しないSpring Securityの使用

SpringセキュリティをSpringまたはSpring MVCで使用しているない場合(つまり、既存のWebApplicationInitializerがない場合)、以下を提供する必要があります次の追加クラス:

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

public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {

    public SecurityWebApplicationInitializer() {
        super(SecurityConfig.class);
    }
}

ここで、SecurityConfigは、Spring Security Java構成クラスです。

SpringまたはSpring MVCでのSpring Securityの使用

SpringまたはSpring MVCでSpring Securityを使用している場合(つまり、既存のWebApplicationInitializerがある場合)、最初に次の追加クラスを提供する必要があります。

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

public class SecurityWebApplicationInitializer
    extends AbstractSecurityWebApplicationInitializer {
}

次に、Spring Security Java構成クラス、この例ではSecurityConfig)が既存のSpringまたはSpring MVC WebApplicationInitializerで宣言されていることを確認する必要があります。次に例を示します。 :

import org.springframework.web.servlet.support.*;

public class MvcWebApplicationInitializer
    extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] {SecurityConfig.class};
    }

    // ... other overrides ...
}
14
Mark Hobson
Dynamic securityFilter = servletContext.addFilter(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME, DelegatingFilterProxy.class);
securityFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");

EnumSet.allOf(DispatcherType.class)デフォルトのDispatcherType.REQUESTだけでなくDispatcherType.FORWARDなどのマッピングを追加するようにしてください...

8
Maksym Demidas

少し作業をした後、私はそれが実際には非常に単純であることを発見しました:

public class Initialiser extends AbstractAnnotationConfigDispatcherServletInitializer implements WebApplicationInitializer {

    @Override
    protected Class< ? >[] getRootConfigClasses() {
        return new Class[] { RootConfig.class };
    }

    @Override
    protected Class< ? >[] getServletConfigClasses() {
        return new Class[] { WebAppConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    protected Filter[] getServletFilters() {
        return new Filter[] { new DelegatingFilterProxy("springSecurityFilterChain") };
    }
}

ただし、最も重要なことは、必須にルートコンテキスト(この場合はRootConfig)があり、すべてのSpringセキュリティ情報への参照が含まれている必要があることです。

したがって、私のRootConfigクラス:

@ImportResource("classpath:spring/securityContext.xml")
@ComponentScan({ "com.example.authentication", "com.example.config" })
@Configuration
public class RootConfig {

    @Bean
    public DatabaseService databaseService() {
        return new DefaultDatabaseService();
    }

    @Bean
    public ExceptionMappingAuthenticationFailureHandler authExceptionMapping() {
        final ExceptionMappingAuthenticationFailureHandler emafh = new ExceptionMappingAuthenticationFailureHandler();
        emafh.setDefaultFailureUrl("/loginFailed");
        final Map<String, String> mappings = new HashMap<>();
        mappings.put(CredentialsExpiredException.class.getCanonicalName(), "/change_password");
        emafh.setExceptionMappings(mappings);
        return emafh;
    }
}

そしてspring/securityContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans  xmlns="http://www.springframework.org/schema/beans"
        xmlns:security="http://www.springframework.org/schema/security"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:noNamespaceSchemaLocation="http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <security:http security="none" pattern="/favicon.ico"/>

    <!-- Secured pages -->
    <security:http use-expressions="true">
        <security:intercept-url pattern="/login" access="permitAll" />
        <security:intercept-url pattern="/**" access="isAuthenticated()" />
        <security:form-login default-target-url="/index" login-processing-url="/login_form" login-page="/login" authentication-failure-handler-ref="authExceptionMapping" />
    </security:http>

    <security:authentication-manager>
        <security:authentication-provider ref="customAuthProvider" />
    </security:authentication-manager>
</beans>

RootConfigクラスとWebAppConfigクラスをWebAppConfigだけにマージし、次のようにした場合、機能しませんでした。

@Override
protected Class< ? >[] getRootConfigClasses() {
    return null;
}

@Override
protected Class< ? >[] getServletConfigClasses() {
    return new Class[] { WebAppConfig.class };
}
3
ipsi
_public class SIServerSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    @Override
    protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
        Dynamic registration = servletContext.addFilter("TenantServletFilter", TenantServletFilter.class);
        EnumSet<DispatcherType> dispatcherTypes = getSecurityDispatcherTypes();
        registration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), false, "/*");
    }

}
_

このシナリオは、他のフィルターを実行する前にフィルターを実行するためのものです。他のファイラーがtrueregistration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");に渡した後にフィルターを実行する場合。 DispatcherType ASYNC、FORWARDなども確認してください。

2
Deepak

これは、セキュリティを備えたSpring Bootに関心がある人に関連しています。何も必要ありません。SpringBootは@コンポーネントを取得し、他の問題を解決します

0
Johnny Bigoode

同じ問題に直面しました。 RootConfigとWebAppConfigをマージします-最善の方法ではありません-これはこのソリューションを試していないためです。他のすべてのソリューションを試しました-いつでも「org.Apache.catalina.core.StandardContext.startInternal Error filterStart」が発生しました。いくつかの作業の後、次のようなものを得ました:

    FilterRegistration.Dynamic enc= servletContext.addFilter("encodingFilter",
            new CharacterEncodingFilter());
    encodingFilter .setInitParameter("encoding", "UTF-8");
    encodingFilter .setInitParameter("forceEncoding", "true");
    encodingFilter .addMappingForUrlPatterns(null, true, "/*");

ただし、DelegatingFilterProxy()では機能しません。すべてのフィルターの最も一般的な解決策を探し続けます。

PDATE:やりました。

したがって、主な問題は、Java configを使用してフィルターを追加する場合、特にDelegatingFilterProxyなどのセキュリティフィルターを追加する場合は、WebAppSecurityConfigを作成する必要があります。

@Configuration
@EnableWebSecurity
@ImportResource("classpath:security.xml")
public class WebAppSecurityConfig extends WebSecurityConfigurerAdapter {
}

この場合、WebAppSecurityConfigを作成し、インポートリソース( "security.xml")を作成します。これにより、初期化クラスでそれを行うことができます:

servletContext.addFilter("securityFilter", new DelegatingFilterProxy("springSecurityFilterChain"))
            .addMappingForUrlPatterns(null, false, "/*");
0
dikkini