最新の安定バージョンについては、Spring Security 6.4.2 を使用してください! |
構成の移行
次の手順は、HttpSecurity
、WebSecurity
、AuthenticationManager
の構成方法に関する変更に関連しています。
@Configuration
アノテーションを追加
6.0 では、@Configuration
が @EnableWebSecurity
、@EnableMethodSecurity
、@EnableGlobalMethodSecurity
、@EnableGlobalAuthentication
から削除されています。
これに備えるために、これらのアノテーションのいずれかを使用している場合は、@Configuration
を追加する必要がある場合があります。例: @EnableMethodSecurity
の変更:
Java
@EnableMethodSecurity
public class MyConfiguration {
// ...
}
Kotlin
@EnableMethodSecurity
open class MyConfiguration {
// ...
}
to:
Java
@Configuration
@EnableMethodSecurity
public class MyConfiguration {
// ...
}
Kotlin
@Configuration
@EnableMethodSecurity
open class MyConfiguration {
// ...
}
新しい requestMatchers
メソッドを使用する
Spring Security 5.8 では、antMatchers
(Javadoc) 、mvcMatchers
(Javadoc) 、regexMatchers
(Javadoc) メソッドが廃止され、新しい requestMatchers
メソッドが採用されました。
新しい requestMatchers
メソッドは、authorizeHttpRequests
、authorizeRequests
、CSRF 構成、WebSecurityCustomizer
、特殊な RequestMatcher
メソッドを持つその他の場所に追加されました。非推奨のメソッドは Spring Security 6 で削除されました。
これらの新しいメソッドは、アプリケーションに最適な RequestMatcher
実装を選択するため、より安全なデフォルトを持っています。要約すると、新しいメソッドは、アプリケーションのクラスパスに Spring MVC がある場合は MvcRequestMatcher
実装を選択し、Spring MVC が存在しない場合は AntPathRequestMatcher
実装にフォールバックします (動作を Kotlin の同等のメソッドに合わせます)。
新しいメソッドの使用を開始するには、非推奨のメソッドを新しいメソッドに置き換えることができます。例: 次のアプリケーション構成:
Java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.antMatchers("/api/admin/**").hasRole("ADMIN")
.antMatchers("/api/user/**").hasRole("USER")
.anyRequest().authenticated()
);
return http.build();
}
}
次のように変更できます。
Java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.requestMatchers("/api/user/**").hasRole("USER")
.anyRequest().authenticated()
);
return http.build();
}
}
クラスパスに Spring MVC があり、mvcMatchers
メソッドを使用している場合は、それを新しいメソッドに置き換えることができ、Spring Security が MvcRequestMatcher
実装を選択します。次の構成:
Java
@Configuration
@EnableWebSecurity
@EnableWebMvc
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.mvcMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
}
次と同等です。
Java
@Configuration
@EnableWebSecurity
@EnableWebMvc
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
}
MvcRequestMatcher
の servletPath
プロパティをカスタマイズしている場合、MvcRequestMatcher.Builder
を使用して、同じサーブレットパスを共有する MvcRequestMatcher
インスタンスを作成できるようになりました。
Java
@Configuration
@EnableWebSecurity
@EnableWebMvc
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.mvcMatchers("/admin").servletPath("/path").hasRole("ADMIN")
.mvcMatchers("/user").servletPath("/path").hasRole("USER")
.anyRequest().authenticated()
);
return http.build();
}
}
上記のコードは、MvcRequestMatcher.Builder
および requestMatchers
メソッドを使用して書き換えることができます。
Java
@Configuration
@EnableWebSecurity
@EnableWebMvc
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http, HandlerMappingIntrospector introspector) throws Exception {
MvcRequestMatcher.Builder mvcMatcherBuilder = new MvcRequestMatcher.Builder(introspector).servletPath("/path");
http
.authorizeHttpRequests((authz) -> authz
.requestMatchers(mvcMatcherBuilder.pattern("/admin")).hasRole("ADMIN")
.requestMatchers(mvcMatcherBuilder.pattern("/user")).hasRole("USER")
.anyRequest().authenticated()
);
return http.build();
}
}
新しい requestMatchers
メソッドに問題がある場合は、使用していた RequestMatcher
実装にいつでも戻すことができます。例: AntPathRequestMatcher
および RegexRequestMatcher
実装を引き続き使用する場合は、RequestMatcher
インスタンスを受け入れる requestMatchers
メソッドを使用できます。
Java
import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
import static org.springframework.security.web.util.matcher.RegexRequestMatcher.regexMatcher;
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authz) -> authz
.requestMatchers(antMatcher("/user/**")).hasRole("USER")
.requestMatchers(antMatcher(HttpMethod.POST, "/user/**")).hasRole("ADMIN")
.requestMatchers(regexMatcher(".*\\?x=y")).hasRole("SPECIAL") // matches /any/path?x=y
.anyRequest().authenticated()
);
return http.build();
}
}
上記のサンプルでは、AntPathRequestMatcher
(Javadoc) および RegexRequestMatcher
(Javadoc) の静的ファクトリメソッドを使用して読みやすさを向上させていることに注意してください。
WebSecurityCustomizer
インターフェースを使用している場合は、非推奨の antMatchers
メソッドを置き換えることができます。
Java
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
}
対応する requestMatchers
を使用:
Java
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().requestMatchers("/ignore1", "/ignore2");
}
同様に、一部のパスを無視するように CSRF 構成をカスタマイズしている場合は、非推奨のメソッドを requestMatchers
メソッドに置き換えることができます。
Java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf((csrf) -> csrf
.ignoringAntMatchers("/no-csrf")
);
return http.build();
}
次のように変更できます。
Java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf((csrf) -> csrf
.ignoringRequestMatchers("/no-csrf")
);
return http.build();
}
新しい securityMatchers
メソッドを使用する
Spring Security 5.8 では、HttpSecurity
の antMatchers
、mvcMatchers
、requestMatchers
メソッドは廃止され、新しい securityMatchers
メソッドが採用されました。
これらのメソッドは、requestMatchers
メソッドを推奨して廃止された authorizeHttpRequests
メソッドと同じではないことに注意してください。ただし、securityMatchers
メソッドは、アプリケーションに最適な RequestMatcher
実装を選択するという意味で、requestMatchers
メソッドと似ています。要約すると、新しいメソッドは、アプリケーションのクラスパスに Spring MVC がある場合は MvcRequestMatcher
実装を選択し、Spring MVC が存在しない場合は AntPathRequestMatcher
実装にフォールバックします (動作を Kotlin の同等のメソッドに合わせます)。securityMatchers
メソッドを追加するもう 1 つの理由は、authorizeHttpRequests
の requestMatchers
メソッドとの混同を避けるためです。
次の構成:
Java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**", "/app/**")
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
securityMatchers
メソッドを使用して書き換えることができます。
Java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.securityMatcher("/api/**", "/app/**")
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
HttpSecurity
構成でカスタム RequestMatcher
を使用している場合:
Java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.requestMatcher(new MyCustomRequestMatcher())
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
public class MyCustomRequestMatcher implements RequestMatcher {
// ...
}
securityMatcher
を使用して同じことができます:
Java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.securityMatcher(new MyCustomRequestMatcher())
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/api/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
public class MyCustomRequestMatcher implements RequestMatcher {
// ...
}
HttpSecurity
構成で複数の RequestMatcher
実装を組み合わせる場合:
Java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.requestMatchers((matchers) -> matchers
.antMatchers("/api/**", "/app/**")
.mvcMatchers("/admin/**")
.requestMatchers(new MyCustomRequestMatcher())
)
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
securityMatchers
を使用して変更できます。
Java
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.securityMatchers((matchers) -> matchers
.requestMatchers("/api/**", "/app/**", "/admin/**")
.requestMatchers(new MyCustomRequestMatcher())
)
.authorizeHttpRequests((authz) -> authz
.requestMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
RequestMatcher
実装を選択する securityMatchers
メソッドに問題がある場合は、いつでも自分で RequestMatcher
実装を選択できます。
Java
import static org.springframework.security.web.util.matcher.AntPathRequestMatcher.antMatcher;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.securityMatchers((matchers) -> matchers
.requestMatchers(antMatcher("/api/**"), antMatcher("/app/**"))
)
.authorizeHttpRequests((authz) -> authz
.requestMatchers(antMatcher("/api/admin/**")).hasRole("ADMIN")
.anyRequest().authenticated()
);
return http.build();
}
WebSecurityConfigurerAdapter
の使用をやめる
SecurityFilterChain
Bean を発行する
Spring Security 5.4 は、WebSecurityConfigurerAdapter
を継承する代わりに SecurityFilterChain
Bean を公開する機能を導入しました。6.0 では、WebSecurityConfigurerAdapter
が削除されます。この変更に備えるために、次のような構造を置き換えることができます。
Java
Kotlin
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.httpBasic(withDefaults());
}
}
@Configuration
open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
@Override
override fun configure(val http: HttpSecurity) {
http {
authorizeHttpRequests {
authorize(anyRequest, authenticated)
}
httpBasic {}
}
}
}
with:
Java
Kotlin
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.httpBasic(withDefaults());
return http.build();
}
}
@Configuration
open class SecurityConfiguration {
@Bean
fun filterChain(http: HttpSecurity): SecurityFilterChain {
http {
authorizeHttpRequests {
authorize(anyRequest, authenticated)
}
httpBasic {}
}
return http.build()
}
}
WebSecurityCustomizer
Bean を発行する
Spring Security 5.4 は、WebSecurityConfigurerAdapter
の configure(WebSecurity web)
を置き換えるために WebSecurityCustomizer
を導入 [GitHub] (英語) しました。削除の準備として、次のようなコードを置き換えることができます。
Java
Kotlin
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers("/ignore1", "/ignore2");
}
}
@Configuration
open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
override fun configure(val web: WebSecurity) {
web.ignoring().antMatchers("/ignore1", "/ignore2")
}
}
with:
Java
Kotlin
@Configuration
public class SecurityConfiguration {
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
}
}
@Configuration
open class SecurityConfiguration {
@Bean
fun webSecurityCustomizer(): WebSecurityCustomizer {
return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2")
}
}
AuthenticationManager
Bean を発行する
WebSecurityConfigurerAdapter
の削除の一環として、configure(AuthenticationManagerBuilder)
も削除されます。削除の準備は、それを使用する理由によって異なります。
LDAP 認証
LDAP 認証のサポートに auth.ldapAuthentication()
を使用している場合は、次のものを置き換えることができます。
Java
Kotlin
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.ldapAuthentication()
.userDetailsContextMapper(new PersonContextMapper())
.userDnPatterns("uid={0},ou=people")
.contextSource()
.port(0);
}
}
@Configuration
open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
override fun configure(auth: AuthenticationManagerBuilder) {
auth
.ldapAuthentication()
.userDetailsContextMapper(PersonContextMapper())
.userDnPatterns("uid={0},ou=people")
.contextSource()
.port(0)
}
}
with:
Java
Kotlin
@Configuration
public class SecurityConfiguration {
@Bean
public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean =
EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();
contextSourceFactoryBean.setPort(0);
return contextSourceFactoryBean;
}
@Bean
AuthenticationManager ldapAuthenticationManager(BaseLdapPathContextSource contextSource) {
LdapBindAuthenticationManagerFactory factory =
new LdapBindAuthenticationManagerFactory(contextSource);
factory.setUserDnPatterns("uid={0},ou=people");
factory.setUserDetailsContextMapper(new PersonContextMapper());
return factory.createAuthenticationManager();
}
}
@Configuration
open class SecurityConfiguration {
@Bean
fun contextSourceFactoryBean(): EmbeddedLdapServerContextSourceFactoryBean {
val contextSourceFactoryBean: EmbeddedLdapServerContextSourceFactoryBean =
EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer()
contextSourceFactoryBean.setPort(0)
return contextSourceFactoryBean
}
@Bean
fun ldapAuthenticationManager(val contextSource: BaseLdapPathContextSource): AuthenticationManager {
val factory = LdapBindAuthenticationManagerFactory(contextSource)
factory.setUserDnPatterns("uid={0},ou=people")
factory.setUserDetailsContextMapper(PersonContextMapper())
return factory.createAuthenticationManager()
}
}
JDBC 認証
JDBC 認証のサポートに auth.jdbcAuthentication()
を使用している場合は、次のものを置き換えることができます。
Java
Kotlin
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.build();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
auth.jdbcAuthentication()
.withDefaultSchema()
.dataSource(this.dataSource)
.withUser(user);
}
}
@Configuration
open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
@Bean
fun dataSource(): DataSource {
return EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.build()
}
override fun configure(val auth: AuthenticationManagerBuilder) {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build()
auth.jdbcAuthentication()
.withDefaultSchema()
.dataSource(this.dataSource)
.withUser(user)
}
}
with:
Java
Kotlin
@Configuration
public class SecurityConfiguration {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION)
.build();
}
@Bean
public UserDetailsManager users(DataSource dataSource) {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource);
users.createUser(user);
return users;
}
}
@Configuration
open class SecurityConfiguration {
@Bean
fun dataSource(): DataSource {
return EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION)
.build()
}
@Bean
fun users(val dataSource: DataSource): UserDetailsManager {
val user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build()
val users = JdbcUserDetailsManager(dataSource)
users.createUser(user)
return users
}
}
インメモリ認証
インメモリ認証のサポートに auth.inMemoryAuthentication()
を使用している場合は、次のものを置き換えることができます。
Java
Kotlin
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
auth.inMemoryAuthentication()
.withUser(user);
}
}
@Configuration
open class SecurityConfiguration: WebSecurityConfigurerAdapter() {
override fun configure(val auth: AuthenticationManagerBuilder) {
val user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build()
auth.inMemoryAuthentication()
.withUser(user)
}
}
with:
Java
Kotlin
@Configuration
public class SecurityConfiguration {
@Bean
public InMemoryUserDetailsManager userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
return new InMemoryUserDetailsManager(user);
}
}
@Configuration
open class SecurityConfiguration {
@Bean
fun userDetailsService(): InMemoryUserDetailsManager {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build()
return InMemoryUserDetailsManager(user)
}
}
@Configuration
から @Enable*
へのアノテーションの追加
6.0 では、すべての Spring Security の @Enable*
アノテーションから @Configuration
が削除されました。便利ではあるものの、残りの Spring プロジェクト、特に Spring Framework の @Enable*
アノテーションとは一貫性がありませんでした。さらに、Spring Framework での @Configuration(proxyBeanMethods=false)
のサポートの導入により、Spring Security の @Enable*
アノテーションから @Configuration
メタアノテーションを削除し、ユーザーが推奨する構成モードを選択できるようにする別の理由が提供されます。
次のアノテーションでは、@Configuration
が削除されました。
@EnableGlobalAuthentication
@EnableGlobalMethodSecurity
@EnableMethodSecurity
@EnableReactiveMethodSecurity
@EnableWebSecurity
@EnableWebFluxSecurity
例: @EnableWebSecurity
を使用している場合は、次のように変更する必要があります。
Java
@EnableWebSecurity
public class SecurityConfig {
// ...
}
to:
Java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
// ...
}
上記の他のすべてのアノテーションにも同じことが当てはまります。
その他のシナリオ
より洗練されたものに AuthenticationManagerBuilder
を使用している場合は、独自の AuthenticationManager
@Bean
を公開するか、HttpSecurity#authenticationManager
(Javadoc) を使用して AuthenticationManager
インスタンスを HttpSecurity
DSL に接続できます。