2016-07-07 2 views
7

私は、スプリングブート、スプリングセキュリティ、およびspring-oauth2に基づいた簡単なOAuth2プロバイダをセットアップしたいと考えています。ステートレススプリングセキュリティoauth2プロバイダ

私はすべてのインスタンスを1台のマシンで処理しています。OAuth2の承認の場合、ユーザーは/oauth/authorizeに送信されます。ほとんどのユーザーはログインしていないので、春のセキュリティで/loginにリダイレクトされた後、/oauth/authorizeに戻ると承認が完了します。

デフォルト設定では、spring-securityはセッションIDを使用してユーザーのブラウザにCookieを設定し、セッションデータをメモリに保存します。ユーザーセッションを失うことなく、ロード・バランシングと青緑色の展開を可能とするために

public static class SecurityConfiguration extends WebSecurityConfigurerAdapter { 
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     http 
      .authorizeRequests() 
      .and() 
      .formLogin() 
      .loginPage("/login") 
      .permitAll(); 
    } 
[...] 

、(私が思う)私は、次の手順を実行する必要があります。

  • 無効にし、サーバー側のセッションを - APIのためOAuth2の承認のみを担当しています。私は、セッション用の共有データベースを持つ必要はないと思います。
  • 代わりに、認証中に一時的にユーザー認証を含むremember-me Cookieを有効にします。
  • Storeは/loginのリダイレクトURLは
    • は、ログインフォームまたはユーザーのCookieでこれを格納することが可能です別の場所にリダイレクトしますか?あるいは、「セッションレス」の代替案は何でしょうか?
  • 無効にCSRF(私はそれを行う方法を知っているとのOAuth2が、私は同様の目的を持っていると思うauth_codesを持っている。ただ、完全性のため。)

は、そのアプローチは理にかなっていますか?どのような変更が必要ですか?

+0

私が大雑把に言ったのは、(a)無効なCSRF(b)リダイレクトURLをクッキーに保存することです。 私はoauth2コード用の記憶域だけが必要です。 – Jan

答えて

0
  1. ユーザーはプロバイダへのログインを行った後、あなたは(リダイレクト(コールバック)URLを介して)クライアントアプリケーションに送信される認証コードを生成します。

  2. その後、クライアントアプリケーションはアクセストークンを取得するようにサーバーに要求します。この要求では、自動化コードが提供されます。

  3. この時点で、クライアントアプリケーションから送信された認証コードと、最初に生成した認証コードを比較できる必要があります。これは共有メモリが必要な場所です。

あなたはプロトコルのこのセクションを見ればsection-4.1あなたは、これはどこのポイントであるので、これは、サーバーの外側の何も達成できない

ポイントCとDの間で共有メモリを必要としますクライアントアプリケーションが承認されていることを確認します。

プロセスの後半でアクセストークンとリフレッシュトークンを使用する場合も同様です。

ログイン手順(ポイントAとB)では、ログインフォーム内にリダイレクトURL(およびクライアント状態 - セクション4.1を参照)があるように見えます。これがセッションが使用される唯一の場所であれば、それを取り除くことができます。しかし、認証コードのために共有メモリ(共有データベース)が必要です。

+0

こんにちはアレックス、あなたはOAuth2フローの説明を与えたが、私の質問に答えなかった。申し訳ありませんが、私はあなたにその恩恵を与えることはできません。 – Jan

+0

はい、あなたは春のセキュリティのコンテキストで何をすべきかの詳細はわかりませんが、私の主張はどんな場合でも共有データベースが必要であるということでした。 –

+0

わかりました、私は実際に共有データベースに認証コードを格納して、その部分が存在するようにします。しかし、私は一般的なセッションストアを取り除くことができるかどうかチェックしたいと思っていました。 – Jan

0

これは、分散セッション記憶域の古典的な問題です。 まず、「セッション」(セッションIDとCookie)と「ステートレス」のコンセプトは矛盾しています。

のOAuth2を使用すると、最初の入力要求アクセスコードを生成する前に、サーバー側で(URLリダイレクトを含む)持続を提供ステートレス」委任承認フレームワークであると考えられます。

資格情報を受け取る前にこれらの詳細をクッキーに漏らすと、セキュリティ上の悪用にさらされる可能性があります。 CookieがHttpOnly(JSではアクセスできない)とsecure(httpSのみで公開されている)であることを確認することでリスクを軽減できますが、私はその方法を推奨しません。

他の点について:Spring Securityのremember-me機能は、最初のauth2要求の詳細ではなく、認証資格情報のみを参照するように設計されています。さらに、永続化されたオプション(PersistentTokenBasedRememberMeServices)は、デフォルトでメモリ(単一ノード)およびjdbcフレーバのみをサポートします。

必要に応じて調整する必要があります。やっても大変な努力が必要です。私の経験で

、頭に浮かぶ二つの選択肢があります:フロントロードバランサ使用

  1. 設定スティッキーセッション(例えば:haproxy、nginxの、F5、などが...)。ユーザーセッションは、送信された資格情報があるノードに関連付けられます。 その意味は、そのノードがダウンした場合です。ユーザーは新しいアクセストークンを作成するために再認証する必要がありますが、すでに与えられているアクセストークンは他のノードに対して使用されていれば問題ありません。

  2. 透明な分散型Webセッションストレージを設定/実装します。 一部の分散メモリストレージプロバイダ(ヘイゼルキャストなど)は、アプリケーションサーバーにこのようなユーザーを透過的にするように構成するpluginsを提供しています。これにはいくつかのオーバーヘッドが追加されていますが、要件を満たすために必要な追加コードはほとんどありません。

関連する問題