Web.xmlファイルの代わりにSpringの新しいWebApplicationInitializer
インターフェイスを使用しているWebアプリケーションにSpring Securityを追加するための推奨される方法は何ですか?私は同等のものを探しています:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
[〜#〜]更新[〜#〜]
提供された回答は合理的ですが、どちらもservletContext
インスタンスがあることを前提としています。私はWebApplicationInitializer
sの階層を調べましたが、Springの初期化メソッドのいずれかをオーバーライドすることを選択しない限り、サーブレットコンテキストへのアクセスは表示されません。 AbstractDispatcherServletInitializer.registerServletFilter
は賢明な選択のように見えますが、デフォルトではURLパターンマッピングに設定されていないため、より良い方法がある場合は、すべてのフィルター登録を変更するのは嫌です。
これは私がそれをした方法です:
container.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain"))
.addMappingForUrlPatterns(null, false, "/*");
コンテナはServletContext
のインスタンスです
Spring Security Reference がこの質問に回答します。解決策は、Spring SecurityをSpringまたはSpring MVCと組み合わせて使用しているかどうかによって異なります。
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を使用している場合(つまり、既存の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 ...
}
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などのマッピングを追加するようにしてください...
少し作業をした後、私はそれが実際には非常に単純であることを発見しました:
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 };
}
_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, "/*");
}
}
_
このシナリオは、他のフィルターを実行する前にフィルターを実行するためのものです。他のファイラーがtrue
をregistration.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
に渡した後にフィルターを実行する場合。 DispatcherType ASYNC、FORWARDなども確認してください。
これは、セキュリティを備えたSpring Bootに関心がある人に関連しています。何も必要ありません。SpringBootは@コンポーネントを取得し、他の問題を解決します
同じ問題に直面しました。 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, "/*");