下記対応は非推奨です。
以下記事の手順で代替してください。
Java認証Proxy対応方法
Depuricated!!
Advent Calendarの第5日目です
タイミングが合ったので乗っかってみました。
環境
環境名 | Version |
---|---|
OS | Ubuntu |
Proxy | Squid-4.13 |
Proxy-Authentication | あり |
IdP | Keycloak-11.0.3 |
Spring-Boot | 2.4.0 |
何がしたかったか。
KeycloakをIdPとして、認証を通した後にOIDCの認可コードフローを回してSpring Sessionを開始したかった。
また、この一連の流れをSpring Securityの設定ベースで実現したかった。
何が起きたか。
Proxyに殺された。
と、冗談は置いといて、以下に最終的な解決方法を示します。
これに至った詳細な経緯も載せておきます。
解決策
javaagentライブラリを開発した。
siersetup/RestTemplateAddonUserSystemProxy
細かいことは上記のReadMeに記載していますが、主な働きとしては、
- RestTemplateのコンストラクタ処理に、JVM引数(プロキシ関連)をまとめて読み込む処理を追加します
これにより、Springフレームワーク側でnew
を用いて生成されるRestTemplate
はすべてプロキシに対応します。
自身のアプリケーション上は、RestTemplateをBean化して、必要なカスタマイズを施して利用します。
以下、経緯を簡単にまとめてみました。
Proxy環境下ではOAuth系のクラスが対応していない
SpringSecuirtyでは、SpringのHttpClientであるRestTemplateが四方八方で使われている。
RestTemplate自体は、requestFactoryを設定することでプロキシ対応は可能である。
しかし、SpringSecurityでは、new RestTemplate()
している箇所が多くまたカプセル化されているため、設定では対応は不可能。
対応方法の検討
リフレクション
リフレクションで対応する、というのはナンセンスだと考えました。
というのも最初はそれでやっていましたが、全貌が見えなかったのと、SpringSecurityすべてのソースを見るという工数的余裕もありませんでした。ボトムアップアプローチはやめました。
RestTemplateの挙動を変える
RestTemplateをプロキシ対応する方法はわかっていたので、SpringSecurityを使う上で、new RestTempalte
はすべてプロキシ対応を打ち込むべきと考えました。
AOP
executionでコンストラクタの前に仕込もうと思いましたが、うまくいきませんでした。
というのも問題箇所は、new RestTemplate
されているだけで、DIのBeanでもなんでもないからです。
javaagent(javassist)
バイトコード書き換えというのは、Lombokを知っていればなんとなく聞いたことがあるものです。
私もその口でしたので、思い切って調べてみました。
意外なほど簡単にコンストラクタを捕捉し、書き換えに成功しました。
後日談
Spring Secuity内のnew RestTemplate()
は6箇所だった
class | 働き | わたしの被弾 |
---|---|---|
NimbusOpaqueTokenIntrospector | OAuth 2.0 Introspection Endpoint を使用してトークンを検証。 | 未使用 |
NimbusJwtDecoder | Nimbus設定を受け取るJwtDecoderの低レベルNimbus実装。 | 被弾 |
DefaultOAuth2UserService | 標準の OAuth 2.0 プロバイダーをサポートする OAuth2UserService の実装。 | 被弾 |
CustomUserTypesOAuth2UserService | @Deprecated |
未使用 |
ClientRegistrations | 提供された発行者に基づいてClientRegistration.Builder、OpenIDプロバイダー構成または 承認サーバーメタデータからを作成できます。 | 被弾 |
JwtDecoderProviderConfigurationUtils |
/.well-known/openid-configuration や/.well-known/oauth-authorization-server などから設定情報を得る。 |
被弾 |
感想
非常に苦しい期間もありましたが、自分なりのOSSを一つ初めて作れたことがとても良かったです。
特に設定だけでOIDC+SpringSecurityを動かせるようにする、というのも普通に理解するのに苦労しました。
最後はProxyにひどいめに合わされましたが、自分なりの解決策に至ったことは大変嬉しく思います。