web-dev-qa-db-ja.com

認証トークンを管理するためのベストプラクティス

私はRESTでクライアントをJava HttpCLientを使用して、REST every REST action。このトークンは24時間有効です。

これを処理する方法は、認証サーバーのオーバーヘッドのように見えるREST呼び出しを行う必要があるたびに "getAuth()"メソッドを呼び出すことです。

この認証トークンを便利に保存し、そのライフサイクルを管理するにはどうすればよいですか?文書化されたベストプラクティスはありますか?

私は次の解決策を考えました

public class MySession {
    String user;
    String pass;
    public MySession(String user, String pass) {
        this.user = user;
        this.pass = pass;
    }

    public getAuth() {
        //user user, pass to get auth token 
    }
}

そして、セッションオブジェクトをトークンが必要なクラスに渡します。トークンの有効期限が切れている場合は、このメソッドを再度呼び出してください

21
user_mda

簡潔にするために、変更できないエンドポイントを呼び出していると仮定します。実装方法は、トークンがアプリベースかユーザーベースか(共有アプリインスタンスのすべてのユーザーに対して1つのトークン、またはユーザーごとに1つのトークン)に大きく依存します。

アプリ全体に対して1つの認証トークンの場合:

  • 有効期限のタイムスタンプとともにメモリに保存します(または、代わりにトークンの期限切れエラーをキャッチし、新しいトークンを要求して元の要求を再試行します)、存在しない/期限切れの場合は更新します
  • アプリケーションの再起動後にAPIトークンを再要求することが心配な場合は、データベースにトークンを保存し、存在する場合は起動時にロードします

ユーザーごとに1つのトークンの場合:

  • ユーザーセッションに保存します。それはまさにセッションの使用目的です。ユーザーを認証している場合、ユーザーはセッションを持ち、オーバーヘッドは既にそこにあります。
  • ログインするたびにトークンを再リクエストしたくない場合は、現在のトークンをDBに保存し、ログイン時にセッションにロードします
7
Dave L

データベースへのヒットが多すぎるのではないかと心配している場合は、Webアクティビティが多いと考えています。

あなたの場合、セッションを使用することはお勧めしませんが、クライアントのCookieにトークンを保存します。

高トラフィック環境(私はあなたの環境だと思います)では、セッションの使用はサーバーメモリを大量に消費する可能性があり、クラスター内でセッションの同期を維持する必要があるため、スケーラビリティも懸念される場合があります。

@CássioMazzochi Molinも言及したように、メモリ内キャッシュを使用してユーザー固有のデータとトークンを保存できます。これにより、データベースへのヒットが減り、必要に応じてアプリケーションを簡単に拡張できます。

3
grizzthedj

次のシナリオを使用することをお勧めします。

1)最初に、auth(username, password) rest apiを呼び出して認証トークンを取得します。指定された資格情報に問題がない場合は、HTTP 200応答コードで認証Cookieをクライアントに返送するだけです。

2)その後、保護されたREST APIを呼び出すことができます。リクエストごとに認証Cookieを送信する必要があります。

3)サーブレットフィルター(または同様のもの)は、各着信要求をチェックし、トークンを検証します。トークンが有効な場合、リクエストはrestメソッドに進みます。そうでない場合、http 401/403レスポンスを生成する必要があります。

独自の認証レイヤーを作成しないことをお勧めします。既存のものをインストールして使用する代わりに。 OpenAM をお勧めします。優れたオープンソースのアクセス管理システムです。

また、認証のためにサーバー側でセッションを開かないことをお勧めします。 10個のクライアントがある場合、10個のセッションをサーバーで管理する必要があります。大きな問題ではありません。ただし、100または1000または数百万の異なるクライアントがある場合、サーバーにセッションを保存するためにより多くのメモリが必要です。

3
zappee

この種のものには、JsonWebToken(略してJWT)を使用する必要があります。 JWTには、有効期限を設定するためのサポートが組み込まれています。この方法を使用するライブラリはたくさんあり、もっと読むことができます here

Currenlty 4 Java実装があり、それらはすべてトークンがまだ有効かどうかを確認できます(exp check) enter image description here

2
Murf

したがって、すべてのリクエストに同じトークンを使用していることを正しく理解している場合(つまり、アプリが実行されてトークンを更新している限り、大丈夫です。文字通り同じ問題があり、これは私はシングルトンクラスを持っていますが、これはアプリの起動時に一度初期化され、無効になったときにトークンを更新します。DIにはC#、Asp.NET MVC5、およびAutoFacを使用していますが、 JavaとSpringでも同じことができます。

スレッドセーフティを使用したシングルトンのプロパティの更新

2
Mavi Domates

以下のコードのように、ローカルのスレッドでログイン中にマネージャーを作成し、auth-cookieを保存できます。スレッドが存続している限り、getAuth()からCookieを取得できます。

public class Manager {
    private static final ThreadLocal<String> SECURITY_CONTEXT = new ThreadLocal<>();

    public static void setAuth(String auth) {
        SECURITY_CONTEXT.set(auth);
    }

    public static String getAuth() {
        return SECURITY_CONTEXT.get();
    }

    public static void clear(){
        SECURITY_CONTEXT.remove();
    }
}
2

事実上の標準は独自のソリューションを実装していません(セキュリティの基本ルール:独自のものを実装しないでください!)、しかし、de-事実上の標準ソリューション、つまり JSON Web Tokens

サイト上のドキュメント、ただし基本的な考え方は、1つの値(サーバーの秘密キー)を保存するだけでよく、その後、サーバーによって最初に発行されたすべてのクレームを検証できます(この場合、有効期限が含まれます) 。

2
D. Kovács

Json Webトークンを使用して、2つのクライアント間で情報を交換します。トークンは24時間のみ存続します。その後、ヘッダー内のすべての結果の呼び出しは拒否されます。

0
Remario