私はREST Webサービスを設計し始めており、認証への最善のアプローチについては不明です。このサービスにより、個々のユーザーが自分のデータにアクセス/管理できるようになります。私はこれらのオプションを見てきました:
OAuthは、認証ではなく承認に重点を置いているようです。サービス内でネイティブに承認を処理する予定なので、これに対する解決策を探していません。しかし、OAuthも認証に適していますか?
OpenIDは確かに認証のためのソリューションを提供しますが、これはユーザーがサードパーティの資格情報(Google、Yahooなど)を使用できるようにすることを目的としています。ユーザーがネイティブの資格情報(メール/パスワード)でサインアップできるようにします。
これは簡単に実装できますが、これは非常に安全な方法ではない可能性があることを理解しています。また、アクセスごとに資格情報の交換が必要なようですが、ユーザーが一度認証してからセッショントークンを介してアクセスを継続することをお勧めします。
基本的に、自分のログイン/トークン生成サービスをロールし、他のすべてのリソースにアクセスするための有効なトークンを要求します(明らかに、すべてがSSLを介します)。
Webサービスの作成と同様に、ユーザーに代わってこれらのサービスを使用するクライアント(Web)アプリケーションも構築しますが、アプリケーションにユーザー情報/資格情報などを保存する必要はありません。だから、このようなもの:
ユーザー(電子メール/パスワードまたはサードパーティの資格情報で認証)-> Webアプリケーション(アプリケーションIDで認証)-> Webサービス
繰り返しになりますが、他のユーザーもクライアントを構築できるようにしたいので、中間層は任意のサードパーティアプリケーションにできます。
ユーザー(電子メール/パスワードまたはサードパーティの資格情報で認証)->サードパーティアプリケーション(アプリケーションIDで認証)-> Webサービス
私の最上位の要件は次のとおりです。
したがって、私の質問は、上記に基づいて(これがあいまいすぎる場合はお知らせください)、「最良の」アプローチはありますか? OAuthまたはOpenIDが適切か、またはこれをあまりにも複雑にしていますか?
編集:
次を実装する必要があると思います。
1)ネイティブの資格情報/トークン(SSLを介したHTTP基本認証?)
2)私のapiが他の場所でホストされているOpenIDを使用できるようにするためのOpenID「依存パーティ」(つまり、「サードパーティの資格情報のサポート」)
3)OAuth "Consumer"を使用して、APIがサードパーティサービスにアクセスできるようにします(ユーザーのLinkedInプロファイルへのアクセスなど)。
4)他の場所でAPIのネイティブIDを使用できるようにするOpenID「プロバイダー」(オプション)
5)OAuth "Provider"により、サードパーティのアプリがユーザーに代わって自分のAPIにアクセスできるようにします(オプション)
これは正しいように見えますか、それとも必要以上に複雑にしていますか?
JWT(JSON Web Token)を検討できます( JWTドラフトrfc を参照)。セキュリティとセッションの有効期限の要件を確実に満たします。ただし、ドラフト標準であるため、現在広く使用されることはまずありません。JWTはOAuth 2.0の一部であるため、すぐに変更される可能性があります。簡単な説明として、JWTトークンは3つの部分(header、body、signature)で構成されます。headerとbodyは、basee64urlエンコード(アルファベットはbase64と最後の2文字分異なります)し、HMAC256(または別のヘッダーで指定されたアルゴリズム)RFCはこの署名を正確に生成する方法を説明しています。これを確認することもできます オンライントークンジェネレーター 。
JWTは、HTTPヘッダーであり、クエリパラメーターに対応しています。
検討すべき適切なオプションの1つは、「共有キー認証」です。これは、Amazon WebサービスとWindows Azureストレージサービスが使用する認証の種類です。開発したRESTサービスで共有キー認証を使用しました。Googleで「共有キー認証」のクイック検索を実行すると、多くの詳細を取得できます。
私は1つのブログ記事を書きました here これについて。
高レベルの手順は次のとおりです。
私の提案は、最初のリクエストを認証してからセッショントークンを設定することです。
フロントエンドアプリケーションはトークンを保存し、後続の各リクエストでトークンを提供します。
トークンには有効期限があります。トークンは、特定の期間使用されないと有効期限が切れます。
セキュリティを強化するために、トークンを発信元IPアドレスに関連付けることができます。
トークンは、Cookieとして、またはURLのクエリパラメーターの1つとして送信できます。
SSLクライアント認証のわずらわしさが受け入れられる場合、相互SSL認証を使用できます。各クライアントには、サーバーが信頼する証明書をプロビジョニングする必要があります。クライアントを異なる方法で処理する必要がある場合は、同じ証明書でも、異なる証明書でもかまいません。
あなたの要件に基づいて、私はOAuth 2.0
が実際に興味深いオプションであると思う。 OAuthは確かに認証プロトコルですが、Authenticates
およびclientId
を持つクライアントもclientSecret
です。 Client Credential Flow
を使用し、Refresh Token
を含めないことを選択できます。これにより、ユーザーはAccess Token
を取得できます。これは一定の時間が経過すると有効期限が切れます。 OAuthは広く使用されているプロトコルであるため、すでに多くのクライアントおよびサーバー側のライブラリであり、あなたとあなたのクライアントが使用します。
OAuthがアプリケーションにとって重すぎるか複雑すぎると思われる場合は、おそらくHTTPS
よりもBasic Authentication
に固執するでしょう。しかし、同様の質問に対する別の回答でも述べたように、自分の認証メカニズムを発明することは決してありません。
詳細については、以前に私が同様の質問に与えた他の答えも見ることができます: https://stackoverflow.com/a/15003777/849741
転送されたパスワードは実際にはパスワードではなくトークンであり、クライアントが別のリソース要求で取得したHTTP Basic Authを使用できます。クライアントはパスワードを1回だけ提供する必要があります多分別のチャネルを介して)。これは中間者攻撃(メッセージ署名がないため)を保護しませんが、アイデアは常にクライアントに何らかの方法で(つまり、独自の認証サービスで)動的トークンを生成することを要求できるということです。そのトークンをパスワードの置換として送信して、実際のパスワードが絶えずネットワーク上で転送されないようにします。はい、これは「カスタム認証ソリューション」の1つのように見えますが、実際には、セッションバインドまたは再計算されるパスワードとして署名トークンを使用するなど、トークンパスワードに必要なルールを課すことができるからではありませんリクエストごとに(シークレットを共有せずに)サーバーがメッセージを検証できるようにします-どんなニーズでも。検証トークンをHTTP Basic Authリクエストの「パスワード」として送信し、より複雑なプロトコルに依存せず、それらを(オプションで)除外しないという考え方です。
OAuth 2.0は、認証のみが必要な場合の方法です。認証を提供し、OAuth2をサポートする OpenID Connect を使用できます。承認のための.0。 OepnID Connectには、自分でサービスをセットアップする必要がある場合に利用できる認定製品が多数あります。また、多くのオンラインサービスも利用できます。
RESTful WebサービスにSpring Bootを使用することをお勧めします。これは、Spring Securityを使用して、テンプレートに基づいて独自のカスタム認証を実装できるためです。ベースセキュリティクラスとインターフェイスをそれぞれ拡張または実装することにより、独自のカスタム認証を実装できます。必要に応じて、Spring Bootにリストした他の認証メカニズムを組み込むオプションもあります。