尝试使用Spring Boot和Spring Security(SecurityFilterChain)

首先

我在个人学习中正在开发的web服务中尝试添加登录功能,原本打算使用之前学习过的Spring Security,但由于WebSecurityConfigurerAdapter已经被弃用,所以我进行了其他的调查。

这次也兼具输出的目的,我将进行发布。

不推荐的写法(WebSecurityConfigurerAdapter)


@Configuration
@EnablebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Override 
  public void configure(HttpSecurity http)throws Exception {

   // do something
  }
}

正如我之前所述,我继承的WebSecurityConfigurerAdapter已经过时了,我不知道其他的方法,感到非常困惑…

我觉得在Spring Boot的参考书中,只有这种方法被提到得比较多。
(如果有其他方法和详细说明的参考书,请告诉我。)

得出的結論

建议我们使用「SecurityFilterChain」。

具体的例子 (jù tǐ lì zǐ)

以下是基本的设置方式。

package com.example.config;

import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;


@Configuration
public class SecurityConfig {

	@Bean
	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		http.formLogin(login -> login
                // 指定したURLがリクエストされるとログイン認証を行う。
				.loginProcessingUrl("/login") 

                // ログイン時のURLの指定
				.loginPage("/login")  

               // 認証成功後にリダイレクトする場所の指定
				.defaultSuccessUrl("/")  

               // ログインに失敗した時のURL
				.failureUrl("/login?error")  

              //アクセス権限の有無(permitAllは全てのユーザーがアクセス可能)
				.permitAll()                  
		).logout(logout -> logout
				.logoutSuccessUrl("/")

             //アクセス制限
		).authorizeHttpRequests(ahr -> ahr
				.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
				.mvcMatchers("/").permitAll()

                //"/admin"はADMIN権限のあるものだけがアクセスできる
				.mvcMatchers("/admin").hasRole("ADMIN")  

                //他のリンクは全て認証が必要である。
				.anyRequest().authenticated()           
				);
		/**
		 * HttpSecurityオブジェクトを生成し、オブジェクトもしくはnullを返す。
		 * build()メソッドはHttpSecurityBuilderインターフェースのメソッド。
		 * HttpSecurityBuilderは、
		 * HttpSecurity、WebSecurityなどの実装クラス
		 * HttpSecurityは、DefaultSecurityFilterChainインターフェースを実装しており、
		 * DefaultSecurityFilterChainはSecurityFilterChainを実装しているため、ポリモーフィズム的にも正しい。
		 */
		return http.build();  
		
	}
}

与以前不同的是,

①不再需要继承WebSecurityConfigurerAdapter。

不再需要覆盖configure方法。

由于方法使用了Lambda表达式,所以处理稍微有些难懂。(※: 被称为Lambda DSL)

需要将SecurityFilterChain注册为Bean,并作为返回值返回。 (http.build()生成HttpSecurity对象并返回为返回值)

这种感觉是存在的。
关于这个SecurityFilterChain并不是新的,似乎很早以前就有了,但是似乎无法注册SecurityFilterChain作为Bean,从Spring Security 5.4开始,似乎可以注册Bean了。

请查看官方博客以了解更详细的信息。

■公式博客↓

 

关于补充(Lambda DSL)

Lambda DSL,中文翻译为”Lambda领域特定语言”。

简单来说,

通过使用Λ可以扩展DSL来设置HTTP安全性。

听起来像是这样的情况。
虽然我还没有完全理解,但根据看了官方博客的感觉,似乎有以下优势。

只需要一个选项,对以下内容进行中文本地化改写:
①不再需要使用and()方法进行连接。
②结果是可读性提高(代码变得更易读)。

确实,每次进行formLogin(登录时的认证),authorizeRequests(访问控制),logout(登出时的设置)等设置时都使用and()方法进行连接,写起来很麻烦,而且方法越来越多,阅读起来有些困难。?

确实,每次要进行formLogin(登录时的认证)、authorizeRequests(访问控制)和logout(登出时的设置)等设置时,都需要使用and()方法进行连接,这样写起来很繁琐,而且随着方法增多,阅读起来也变得有些困难。?

具體的例子

最后,我们来确认一下实际使用Lambda DSL和不使用Lambda DSL的例子。

■使用Lambda DSL的例子

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests(authorizeRequests ->
                authorizeRequests
                    .antMatchers("/blog/**").permitAll()
                    .anyRequest().authenticated()
            )
            .formLogin(formLogin ->
                formLogin
                    .loginPage("/login")
                    .permitAll()
            )
            .rememberMe(withDefaults());
    }
}

不使用Lambda DSL的案例。

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/blog/**").permitAll()
                .anyRequest().authenticated()
                .and() // ←ここ
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and() // ←ここ
            .rememberMe();
    }
}

公式博客(关于Lambda DSL)↓

 

资料、文献、引用资料、引证资料

■ 公式博客

 

■有关Spring Security的Qiita投稿

 

■ HttpSecurity 类

 

■DefaultSecurityFilterChain类

 

■安全过滤器链接口

 

■httpSecurityBuilder接口

 

■Spring Security的配置

 

广告
将在 10 秒后关闭
bannerAds