6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JavaAdvent Calendar 2020

Day 5

Proxy環境下のSpring Securityを攻略する

Last updated at Posted at 2020-12-04

下記対応は非推奨です。

以下記事の手順で代替してください。
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箇所だった

image.png

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にひどいめに合わされましたが、自分なりの解決策に至ったことは大変嬉しく思います。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?