Open6
Microsoft Entra ID OAuth 2.0 Login with Spring Security

最後に見るのは公式情報定期

application.yaml のポイント
-
issuer-uri
は御作法なので設定忘れない -
provider
で設定した値は registration の provider での指定に使用する (この例だと azure-active-directory) -
registration
で設定する値は、サービスプリンシパルのリダイレクト URI で使用される値になるので注意 (この例だと spring-boot-sample)
application.yaml
spring:
security:
oauth2:
client:
provider:
azure-active-directory:
issuer-uri: https://login.microsoftonline.com/<テナントID>/v2.0 # 御作法
registration:
spring-boot-sample: # ここはリダイレクトURIの一部に使われる値になる
provider: azure-active-directory # 上段の provider で定義している値を指定
client-id: <サービスプリンシパルのクライアントID>
client-secret: <サービスプリンシパルのシークレット値>
scope:
- openid
- email
- profile

SecurityConfig の SecurityFilterChain
でアクセスするページの認可を制御したい場合は
- authorizeHttpRequests でアクセス先のページの認可を定義
- oauth2Login はいったんデフォルト踏襲(後述でカスタマイズ)
WebSecurityConfig.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
.requestMatchers("/").permitAll()
.requestMatchers("/welcome").authenticated()
.requestMatchers("/admin").hasRole("Admin")
.anyRequest().denyAll())
.oauth2Login(Customizer.withDefaults());
return http.build();
}
}

やっはり最後に見るのは公式Docs

OAuth2 Loginでログインページをカスタマイズしたい場合は、oauth2Login
を書き換え、ログインページのhtmlでログインボタンの遷移先を/oauth2/authorization/{registrationで設定した値}
にする
oauth2Login については、
- loginPage は
/login/oauth2
固定、かつ @Controller で @GetMapping 指定を忘れない - loginProcessingUrl はリダイレクトURLのURI
- defaultSuccessUrl はログイン成功時に遷移するページの指定
- authorizationEndpoint の指定はオプションだが、デフォルト設定を踏襲
- 最後の permitAll() を忘れると永遠とログイン認証のリダイレクトが走るので指定を忘れない
WebSecurityConfig.java
@Configuration
@EnableWebSecurity
public class WebSecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
... // 省略
)
.oauth2Login(oauth2 -> oauth2
.loginPage("/login/oauth2")
.loginProcessingUrl("/login/oauth2/code/*")
.defaultSuccessUrl("/welcome")
.authorizationEndpoint(Customizer.withDefaults())
.permitAll());
return http.build();
ログインページの例
login.html
<a href="/oauth2/authorization/spring-boot-sample" class="btn btn-microsoft btn-user btn-block">
<i class="fab fa-fw"></i> Login with Microsoft (work or school)
</a>

Spring Security 5.8 から、未認証時のアクセス時のリクエストキャッシュの動作が代わり、?continue
パラメータが認証後につくようになった
このため、本来存在しないURLにアクセスした場合、
- ログインページにリダイレクト
- 認証
- {本来存在しないURL}?continue へアクセス
という無駄な処理を生む原因になっている
これを防ぐには、NullRequestCacheを実装し、未認証時からのアクセスは全てdefaultSuccessUrlに飛ばすという方法がある
WebSecurityConfig.java
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
RequestCache nullRequestCache = new NullRequestCache();
http
.requestCache(cache -> cache
.requestCache(nullRequestCache))
.authorizeHttpRequests(auth -> auth
... // 省略
)
.oauth2Login(oauth2 -> oauth2
... // 省略
);
return http.build();
}