以前にAzure Active Directory で Spring Boot and OAuth2 - Azureの小ネタ (改) という記事を書いたのですが、Spring 周りも色々アップデートされ、内容が古くなってきているので最新の環境で検証してみた備忘録です。
最近の状況
前記事BLOGで使用したSpring Security OAuth は Deprecatedになっています。またOAuth2 Boot より引用すると以下のようになっています。
The following projects are in maintenance mode:
- spring-security-oauth2
- spring-security-oauth2-autoconfigure
You are, of course, welcome to use them, and we will help you out!
However, before selecting spring-security-oauth2 and spring-security-oauth2-autoconfigure, you should check out Spring Security’s feature matrix to see if the new first-class support meets your needs.
マイグレガイドがあるので、これを読めばよいと思われます。 OAuth 2.0 Migration Guide · spring-projects/spring-security Wiki
準備
AADアプリを登録して以下を取得します。
- テナントID
- クライアントID(アプリケーションID)
- シークレットシークレット(パスワード)
ちょっと古いもしますが、 チュートリアル: Azure Active Directory でアプリを登録する (Common Data Service) - Power Apps | Microsoft Docs を参考にしてください。
プロジェクト
Spring Initializr で、適当にWebアプリをSpring Bootで作りましょう。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> </dependency>
サンプルで使うライブラリはここら辺です。 spring-boot-starter-oauth2-client
と spring-boot-starter-security
がキモでしょうか。
設定
GitHubとかGoogleとかは基本的な設定が取り込まれているようですが、AADはそんなことになってないので、フル設定します。
azuread
という項目は任意の名前で構いません。が、 registration下とprorivder下は同じ名前にしてください。項目名がそのまま説明になっているので補足は特にないです。
spring: devtools: add-properties: true thymeleaf: cache: false security: oauth2: client: registration: # Azure Active Directory azuread: client-id: クライアントID client-secret : クライアントシークレット client-name: Azure Active Directory scope: - profile client-authentication-method: post authorization-grant-type: authorization_code redirect-uri: http://localhost:8080/login/oauth2/code/azuread provider: azuread: token-uri: https://login.microsoftonline.com/テナントID/oauth2/token authorization-uri: https://login.microsoftonline.com/テナントID/oauth2/authorize user-info-uri: https://graph.windows.net/me?api-version=1.6 user-name-attribute: displayName
プログラムの修正
プログラム上での初期化は以下です。 認証を有効にして、例外ページ、ログアウト等などを設定します。
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { private ClientRegistrationRepository repo; public SecurityConfig(ClientRegistrationRepository repo) { this.repo = repo; } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/", "/webjars/**", "/error**").permitAll() .anyRequest().authenticated() .and() .logout() .logoutSuccessUrl("/") .invalidateHttpSession(true) .deleteCookies("JSESSIONID") .and() .oauth2Login() .authorizationEndpoint(); } }
次に resources/templates/index.html を作成してます。Controllerで適宜、このページを返すようにしておいてください。
<!DOCTYPE html> <html lang="en" xmlns:sec="http://www.thymeleaf.org/extras/spring-security"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Home</title> <link rel="stylesheet" th:href="@{/webjars/bulma/0.9.0/css/bulma.min.css}" /> </head> <body> <div class="container is-fluid" style="padding-top:3rem"> <div class="columns"> <h3 class="title">Spring boot oauth2 sample application with AADC.</h3> </div> <div sec:authorize="isAuthenticated()"> <div class="columns"> <div class="column"> Logged inn </div> </div> <div class="columns"> <div class="column"> Hi <span th:text="${#authentication.name}"></span> san! </div> </div> <div class="columns"> <div class="column is-2"> <a href="/logout" class="button is-info">Logout (GET)</a> </div> <div class="column is-2"> <form th:action="@{/logout}" method="post"> <button class="button is-primary" type="submit">Logout (POST)</button> </form> </div> <logout/> </div> </div> <div class="columns"> <div class="column"> <div sec:authorize="isAnonymous()"> <div class="controll"> <a class="button is-primary" href="/login">Login</a> </div> </div> </div> </div> </div> </body> </html>
実行例
mvn clean package spring-boot:run
で実行して、 localhost:8080
にアクセスします。
認証されていないので、Loginボタンがでます。
ボタンを押すと、Providerの選択画面に飛ばされます。複数設定すると複数表示されますが、今回はAADだけなので、AADのみが表示されます。AADを選択すると、MSの例の認証画面に飛ばされるので、AADのアカウントで認証してください。
名前が表示されればOKです。LogoutはGETとPOSTする方法があって、GETすると結局フレームワーク側が用意するページに一旦飛ばされてPOSTする挙動になるだけです。
まとめ
ほぼフレームワークがやってくれるので、設定方法さえ分ってしまえば特に難しいことは無いと思います。結局、うまく動作しなくて設定で試行錯誤するわけで、こうやってBLOGに備忘録として記録されるわけです。
またサンプルがまとまったらまたGitHubにでもあげておこうかと思います。次回は、AAD B2Cを使った方法でも。