SpringSecurity OAuth2でOpenAMとの連携を試します。
/private
は認証を必要とするエンドポイントで、/public
は認証が不要なエンドポイントです。
また、ログは可能な限り出力する方針とします。SpringSecurityのデバッグログに加えてRestTemplateのリクエストとレスポンスもログに出力します。
1. OpenAMの実行と設定
まずはOpenAMを実行します。
1 |
|
- パスワードの設定しTopLevelのレルムにOAuth2のアプリケーションを作成します。名前は
test
、パスワードはpassword
としました。 Redirection URIs
にhttp://localhost:9000/login/oauth2/code/openam
を追加します。Scope
にemail
を追加します。
2. アプリケーションの作成
application.yml
まずは設定ファイル。8080ポートはOpenAMが使っているので9000にしました。
1 |
|
RestTemplateLoggingInterceptor.java
RestTemplateのログ出力用インターセプターです。説明は省きます。
1 |
|
PrivateController.java, PublicController.java
Restコントローラーです。説明は省きます。
1 |
|
1 |
|
CustomAuthenticationSuccessHandler
AuthenticationSuccessHandlerです。今回なくても問題ないですがログだけ出力するようにしました。
1 |
|
OAuth2UserService.java
OAuth2UserServiceです。ログ出力のためにRestTemplateを上書きします。処理自体はデフォルトのままです。
1 |
|
Application.java
SpringSecurityのデバッグをtrueに設定してます。プロダクション環境ではfalseにしましょう。
1 |
|
SecurityConfig.java
SpringSecurityの設定クラスです。
設定内容は以下のとおりです。
- CustomAuthenticationSuccessHandlerを使用します。
- CustomOAuth2UserServiceを使用します。
- accessTokenResponseClientを設定します。その際、RestTemplateのログを出力するようにします。
/
,/public
は誰でもアクセスできます。それ以外は認証が必要です。
1 |
|
処理の流れ
処理の流れは以下のとおりです。
- ブラウザで
http://localhost:9000/private
にアクセスする - アプリケーションからOpenAMへのリダイレクト指示が返るので、OpenAMのログインページにリダイレクトする
http://localhost:8080/openam/oauth2/authorize?response_type=code&client_id=test&scope=email&state=Sz61Zw0rWrT_GQZsRQqvg-HL_Z8tAzKuCXU2TTkSGX0%3D&redirect_uri=http://localhost:9000/login/oauth2/code/openam
- ID、パスワードを入力しOpenAMにログインする
- OpenAMのレスポンスからアプリケーションへのリダイレクト指示が返るので、アプリケーションにリダイレクトする
http://localhost:9000/login/oauth2/code/openam?code=bf5079d8-6ee3-4ee3-8c50-085ce6ab0e01&scope=email&iss=http%3A%2F%2Flocalhost%3A8080%2Fopenam%2Foauth2&state=Sz61Zw0rWrT_GQZsRQqvg-HL_Z8tAzKuCXU2TTkSGX0%3D&client_id=test
- アプリケーションがOpenAMのAPIを呼び出してアクセストークンを取得する
1
2
3
4
5
6
7
8
9
10
11
12===========================request begin================================================
URI : http://localhost:8080/openam/oauth2/access_token
Method : POST
Headers : [Accept:"application/json;charset=UTF-8", Content-Type:"application/x-www-form-urlencoded;charset=UTF-8", Authorization:"Basic dGVzdDpwYXNzd29yZA==", Content-Length:"147"]
Request body: grant_type=authorization_code&code=bf5079d8-6ee3-4ee3-8c50-085ce6ab0e01&redirect_uri=http%3A%2F%2Flocalhost%3A9000%2Flogin%2Foauth2%2Fcode%2Fopenam
==========================request end================================================
============================response begin==========================================
Status code : 200 OK
Status text :
Headers : [X-Frame-Options:"SAMEORIGIN", Cache-Control:"no-store", Date:"Sat, 11 Jun 2022 07:16:32 GMT", Accept-Ranges:"bytes", Server:"Restlet-Framework/2.4.0", Vary:"Accept-Charset, Accept-Encoding, Accept-Language, Accept", Pragma:"no-cache", Content-Type:"application/json", Transfer-Encoding:"chunked", Keep-Alive:"timeout=20", Connection:"keep-alive"]
Response body: {"access_token":"7b653046-cc64-48bf-aab1-151de16936a4","scope":"email","token_type":"Bearer","expires_in":3599}
=======================response end================================================= - アプリケーションがOpenAMのAPIを呼び出してユーザー情報を取得する
1
2
3
4
5
6
7
8
9
10
11
12===========================request begin================================================
URI : http://localhost:8080/openam/oauth2/userinfo
Method : GET
Headers : [Accept:"application/json", Authorization:"Bearer 7b653046-cc64-48bf-aab1-151de16936a4", Content-Length:"0"]
Request body:
==========================request end================================================
============================response begin==========================================
Status code : 200 OK
Status text :
Headers : [X-Frame-Options:"SAMEORIGIN", Date:"Sat, 11 Jun 2022 07:16:32 GMT", Accept-Ranges:"bytes", Server:"Restlet-Framework/2.4.0", Vary:"Accept-Charset, Accept-Encoding, Accept-Language, Accept", Content-Type:"application/json;charset=UTF-8", Transfer-Encoding:"chunked", Keep-Alive:"timeout=20", Connection:"keep-alive"]
Response body: {"sub":"Taro","email":"taro@example.com"}
=======================response end================================================= - もともとアクセスしようとしていた
http://localhost:9000/private
にリダイレクトする