OpenID Connect は OAuth 2.0 に基づいた軽量な仕様であり、API を介したアイデンティティのやりとりのフレームワークを提供します。 OAuth と比較し、OpenID Connect はリクエストを認証するだけでなく、リクエスト元のアイデンティティも指定します。
OpenID Connect に基づいて、API Gateway には API リクエストを認証する方法が 2 つあります。
OpenID Connect
標準の OpenID Connect に準拠して、API リクエストはまず 「userLoginName」 および 「パスワード」 で 「Token」 を取得します。 それ以降、API リクエストは Token で検証します。
OpenID Connect & AlibabaCloudAPP
OpenID Connect に基づいて、API Gateway はリクエストの Appkey+Token を検証し、Appkey および Token を認証します。 API プロバイダのシステムが Token を発行し、API Gateway が Appkey を発行します。
OpenID Connect および OpenID Connect & AlibabaCloudApp の違いとして、OpenID Connect & AlibabaCloudApp は、APPkey を認証する必要がありますが、OpenID Connect は認証しません。
OpenID Connect でサポートされていない機能
- アプリ承認を使用できません。
- アプリ レベルのスロットリングができません。
- AlibabaCloud アカウント レベルのスロットリングができません。
実装原則
OpenID Connect 認証を実行することで、API を認証 API およびサービス API に分類できます。
- 認証 API:クライアントに Token を発行するために使用されるインターフェイスです。 この類の API を設定するときは、Token に該当する鍵と Token の解決に使用される公開鍵を API Gateway に通知する必要があります。
- サービス API:ユーザー情報を取得して操作の実行に使用されるインターフェイスです。 この類の API を設定するときは、リクエストの Token を表すパラメーターについて API Gateway に通知する必要があります。 リクエストが API Gateway に到達すると、API Gateway はリクエストが有効かどうかを自動的にチェックします。
認証方法
クライアントが認証 API を呼び出します
クライアントは認証を使用して「Token」を取得します。
OpenID Connect
クライアントは ユーザー名/パスワード を使用して認証 API を呼び出して認証 Token を取得します。
OpenID Connect & AlibabaCloudAPP
クライアントは、Appkey 署名+ユーザー名/パスワードを使用して認証 API を呼び出し、認証 Token を取得します。
リクエストを受け取った後、API Gateway は Appkey を最初に認証します(OpenID Connect には必要ありません)。認証に成功すると、API Gateway はバックエンドサービスのアカウント システムを呼び出して、ユーザー名/パスワードを認証します。
バックエンドサービスによる認証に成功すると、返された Token を使用してのサービス API 呼び出しが可能になります。
クライアントがサービス API を呼び出します
クライアントは認証 API および署名された Appkeyによって得られた Token を使用して、サービス API を呼び出します。
API Gateway はTokenを認証して解決し、Token に含まれるユーザー情報をバックエンドに送信します。
この段階では、API プロバイダは事前に次の手順を実行する必要があります。
- アカウントシステムを開き、API Gateway がリクエスト内のユーザー名およびパスワードを認証できるようにし、API Gateway 提供の暗号化モードに基づいて Token を発行します。 詳細は、AS モジュールの実装方法を参照。
- API Gateway で API を定義します。 詳細は、API Gateway での API の設定を参照。
注: ユーザー名およびパスワード は機密情報であり、プレーンテキストで送信すると危険です。 ユーザー名およびパスワードを暗号化し、HTTPS プロトコルを使用して送信することをお勧めします。
実現方法
実現方法には、重要な箇所が 2 つあります。次のとおりです。
1. 認証サーバー(AS): id_token の生成および KeyPair の管理に使用されます。
ご自身でこの手順を行います。 この方法の詳細については、以下のAPI Gateway での API の設定をご参照ください。
上図のプロセスは次のとおりです。
- Consumer(呼び出し元)は、API Gateway に id_token 認証リクエストを送信します(たとえば、ユーザー名+パスワード(U+P)モード)。
- API Gateway は、透過的にリクエストを AS に送信します。
- AS は、ユーザー認証リクエストを Provider(サービスプロバイダー)に送信します。
- Provider は認証結果を返すか、認証に失敗した場合はエラーメッセージを返します。
- 認証に成功すると、AS は id_token を生成します。 id_token は、User 情報(拡張可能であり、その他に必要な情報を含むことができます)を含みます。
API Gateway は、AS によって返された id_token を Consumer に送信します。
注意: AS は個別にデプロイする必要はありません。AS は Provider に統合することができ、システム全体で id_token を生成するために使用されます。 生成された id_token は、OIDC プロトコル(バージョン1.0)の仕様を満たす必要があります。
2. リソースサーバー(RS):id_token を認証し、該当する情報を解決するために使用されます。
ここは API Gateway によって実装されています。 RS 機能は API Gateway に統合されているため、Provider は該当する暗号化ルールに従って id_token を生成するだけで済みます。
上図のプロセスは次のとおりです。
- Consumer は、id_token を持つパラメーターを API Gateway に送信します。
- API Gateway は、検証に使用される publicKey を保存し、id_token を検証して解決し、ユーザー情報を取得し、ユーザー情報を Provider に送信します。 検証に失敗すると、API Gateway はエラーメッセージを返します。
- Provider はリクエストを処理し、結果を API Gateway に返します。
- API Gateway は、Provider からの結果を Consumer に透過的に送信します。
注意: RS は id_token の Consumer として機能します。 id_token 検証が成功した場合にのみ、リクエストを Provider に転送することができます。
AS モジュールの実装方法
AS 内の OIDC を使用した id_token の生成
- id_token は、ID Token とも呼ばれ、OIDC プロトコルで定義されたトークンの一種です。 詳細は、OpenID Connect Core 1.0 を参照。
- KeyPair、keyId、および Claims は、id_token を生成するために必要です (Claims の詳細は、ID_Token を参照)。
KeyId の説明
KeyId は一意でなければなりません。 たとえば、UUID を使用して生成された KeyId は、少なくとも 32 のランダムな文字列です(すべて数字、または、数字および文字)。
例(Java)
また
- String keyId = UUID.randomUUID().toString().replaceAll("-", "");
- String keyId = String.valueOf(UUID.randomUUID().getMostSignificantBits()) + String.valueOf(UUID.randomUUID().getMostSignificantBits());
KeyPair の説明
KeyPair は、非対称アルゴリズムを使用する PKI システムベースの公開鍵および秘密鍵のペアです。 各ペアには、publicKey および privateKey があります。 publicKey は検証に使用される RS に格納されます。 privateKey は、id_token が生成されたときにデジタル署名として機能する AS に格納されます。
KeyPair は、RSA SHA256 暗号化アルゴリズムを使用します。 セキュリティを保証するために、2,048ビットが暗号化されています。
AS で使用されるすべての KeyPairs は JSON 形式です。 以下はその例です。
publicKey:
privateKey:
- {"kty":"RSA","kid":"67174182967979709913950471789226181721","alg":"ES256","n":"oH5WunqaqIopfOFBz9RfBVVIIcmk0WDJagAcROKFiLJScQ8N\_nrexgbCMlu-dSCUWq7XMnp1ZSqw-XBS2-XEy4W4l2Q7rx3qDWY0cP8pY83hqxTZ6-8GErJm\_0yOzR4WO4plIVVWt96-mxn3ZgK8kmaeotkS0zS0pYMb4EEOxFFnGFqjCThuO2pimF0imxiEWw5WCdREz1v8RW72WdEfLpTLJEOpP1FsFyG3OIDbTYOqowD1YQEf5Nk2TqN\_7pYrGRKsK3BPpw4s9aXHbGrpwsCRwYbKYbmeJst8MQ4AgcorE3NPmp-E6RxA5jLQ4axXrwC0T458LIVhypWhDqejUw","e":"AQAB"}
- {"kty":"RSA","kid":"67174182967979709913950471789226181721","alg":"ES256","n":"oH5WunqaqIopfOFBz9RfBVVIIcmk0WDJagAcROKFiLJScQ8N\_nrexgbCMlu-dSCUWq7XMnp1ZSqw-XBS2-XEy4W4l2Q7rx3qDWY0cP8pY83hqxTZ6-8GErJm\_0yOzR4WO4plIVVWt96-mxn3ZgK8kmaeotkS0zS0pYMb4EEOxFFnGFqjCThuO2pimF0imxiEWw5WCdREz1v8RW72WdEfLpTLJEOpP1FsFyG3OIDbTYOqowD1YQEf5Nk2TqN\_7pYrGRKsK3BPpw4s9aXHbGrpwsCRwYbKYbmeJst8MQ4AgcorE3NPmp-E6RxA5jLQ4axXrwC0T458LIVhypWhDqejUw","e":"AQAB","d":"aQsHnLnOK-1xxghw2KP5JTZyJZsiwt-ENFqqJfPUzmlYSCNAV4T39chKpkch2utd7hRtSN6Zo4NTnY8EzGQQb9yvunaiEbWUkPyJ6kM3RdlkkGLvVtp0sRwPCZ2EAYBlsMad9jkyrtmdC0rtf9jerzt3LMLC7XWbnpC3WAl8rsRDR1CGs\_-u4sfZfttsaUbJDD9hD0q4NfLDCVOZoQ\_8wkZxyWDAQGCe6GcCbu6N81fTp2CSVbiBj7DST\_4x2NYUA2KG8vyZYcwviNTxQzk4iPfdN2YQz\_9aMTZmmhVUGlmTvAjE5ebBqcqKAS0NfhOQHg2uR46eBKBy\_OyVOLohsQ","p":"8Tdo3DCs-0t9JMtM0lYqPRP4wYJs37Rv6S-ygRui2MI\_hadTY9I2A199JMYw7Fjke\_wa3gqJLa98pbybdLWkrOxXbKEkwE4uc4-fuNjLbUTC5tqdM5-nXmpL887uREVYnk8FUzvWeXYTCNCb7OLw5l8yPJ1tR8aNcd0fJNDKh98","q":"qlRrGSTsZzBkDgDi1xlCoYvoM76cbmxrCUK-mc\_kBRHfMjlHosxFUnAbxqIBE4eAJEKVfIJLQrHFvIDjQb3kM9ylmwMCu9f8u9DHrT8J7LSDlLqDaXuiM2oiKtW3bAaBPuiR7sVMFcuB5baCebHU487YymJCBTfeCZtFdi6c4w0","dp":"gVCROKonsjiQCG-s6X4j-saAL016jJsw-7QEYE6uiMHqR\_6iJ\_uD1V8Vuec-RxaItyc6SBsh24oeqsNoG7Ndaw7w912UVDwVjwJKQFCJDjU0v4oniItosKcPvM8M0TDUB1qZojuMCWWRYsJjNSWcvAQA7JoBAd-h6I8AqT39tcU","dq":"BckMQjRg2zhnjZo2Gjw\_aSFJZ8iHo7CHCi98LdlD03BB9oC\_kCYEDMLGDr8d7j3h-llQnoQGbmN\_ZeGy1l7Oy3wpG9TEWQEDEpYK0jWb7rBK79hN8l1CqyBlvLK5oi-uYCaiHkwRQ4RACz9huyRxKLOz5VvlBixZnFXrzBHVPlk","qi":"M5NCVjSegf\_KP8kQLAudXUZi\_6X8T-owtsG\_gB9xYVGnCsbHW8gccRocOY1Xa0KMotTWJl1AskCu-TZhOJmrdeGpvkdulwmbIcnjA\_Fgflp4lAj4TCWmtRI6982hnC3XP2e-nf\_z2XsPNiuOactY7W042D\_cajyyX\_tBEJaGOXM"}
KeyPair(Java)の生成例
- import java.security.PrivateKey;
- import org.jose4j.json.JsonUtil;
- import org.jose4j.jwk.RsaJsonWebKey;
- import org.jose4j.jwk.RsaJwkGenerator;
- import org.jose4j.jws.AlgorithmIdentifiers;
- import org.jose4j.jws.JsonWebSignature;
- import org.jose4j.jwt.JwtClaims;
- import org.jose4j.jwt.NumericDate;
- import org.jose4j.lang.JoseException;
- String keyId = UUID.randomUUID().toString().replaceAll("-", "");
- RsaJsonWebKey jwk = RsaJwkGenerator.generateJwk(2048);
- jwk.setKeyId(keyId);
- jwk.setAlgorithm(AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256);
- String publicKey = jwk.toJson(RsaJsonWebKey.OutputControlLevel.PUBLIC_ONLY);
- String privateKey = jwk.toJson(RsaJsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
id_token の生成プロセス
OIDC プロトコルで定義された Claims 属性(aud、sub、exp、iat および iss)および属性値を使用して Claims(完全名は JwtClaims)を生成します。
コード例(Java)
- JwtClaims claims = new JwtClaims();
- claims.setGeneratedJwtId();
- claims.setIssuedAtToNow();
- //expire time
- NumericDate date = NumericDate.now();
- date.addSeconds(120);
- claims.setExpirationTime(date);
- claims.setNotBeforeMinutesInThePast(1);
- claims.setSubject("YOUR_SUBJECT");
- claims.setAudience("YOUR_AUDIENCE");
- //Add custom parameters
- claims.setClaim(key, value);
keyId、Claims、privateKey、およびデジタル署名アルゴリズム(RSA SHA256)を使用して JSON Web Signature(JWS)を生成します。
コード例(Java)
- JsonWebSignature jws = new JsonWebSignature();
- jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
- jws.setKeyIdHeaderValue(keyId);
- jws.setPayload(claims.toJson());
- PrivateKey privateKey = new RsaJsonWebKey(JsonUtil.parseJson(privateKeyText)).getPrivateKey();
- jws.setKey(privateKey);
id_token の値を取得するには、JWS を使用します。
コード例(Java)
- String idToken = jws.getCompactSerialization();
生成された id_token 例
- eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg4NDgzNzI3NTU2OTI5MzI2NzAzMzA5OTA0MzUxMTg1ODE1NDg5In0.eyJ1c2VySWQiOiIzMzcwMTU0NDA2ODI1OTY4NjI3IiwidGFnTmFtZSI6ImNvbmFuVGVzdCIsImV4cCI6MTQ4MDU5Njg3OSwiYXVkIjoiQWxpX0FQSV9Vc2VyIiwianRpIjoiTm9DMFVVeW5xV0N0RUFEVjNoeEIydyIsImlhdCI6MTQ4MDU5MzI3OSwibmJmIjoxNDgwNTkzMjE5LCJzdWIiOiJ7ZGF0YU1hcD0ne3VzZXJJZD0zMzcwMTU0NDA2ODI1OTY4NjI3fScsIHN0YXR1c0NvZGU9JzAnLCBlcnJvcnM9J1tdJ30ifQ.V3rU2VCziSt6uTgdCktYRsIwkMEMsO_jUHNCCIW_Sp4qQ5ExjtwNt9h9mTGKFRujk2z1E0k36smWf9PbNGTZTWmSYN8rvcQqdsupcC6LU9r8jreA1Rw1CmmeWY4HsfBfeInr1wCFrEfZl6_QOtf3raKSK9AowhzEsnYRKAYuc297gmV8qlQdevAwU75qtg8j8ii3hZpJqTX67EteNCHZfhXn8wJjckl5sHz2xPPyMqj8CGRQ1wrZEHjUmNPw-unrUkt6neM0UrSqcjlrQ25L8PEL2TNs7nGVdl6iS7Nasbj8fsERMKcZbP2RFzOZfKJuaivD306cJIpQwxfS1u2bew
API Gateway で API の設定
API 編集機能では、基本情報のセキュリティ認証に OpenID Connect オプションが追加されています。 Alibaba Cloud アプリ認証方法も含まれています。 つまり、認証済みアプリだけがこの API を呼び出すことができます。
OpenID Connectを選択したら、OpenID Connect モードを設定します。 次の 2 つのオプションが用意されています。
- 認証 API:たとえば U+P を使用して Token を取得するなど、Token を取得するために使用されます。
- ビジネス API:プロバイダがサービスを提供するために使用します。ユーザーは取得した Token を入力パラメーターとして呼び出します。
OpenID Connect 認証方法は、前述の 2 種類の API に使用されます。 次のセクションでは、これらの 2 つのタイプの API をそれぞれ設定する方法について説明します。
- 認証 API:たとえば U+P を使用して Token を取得するなど、Token を取得するために使用されます。
認証 API の場合は、下図のとおり、KeyId および publicKey を設定する必要があります。
KeyId: AS によって生成される KeyPair に該当する一意の ID です。 たとえば、
publicKey: AS によって生成された Token の認証および解決に使用されます。 たとえば、- 88483727556929326703309904351185815489
- {"kty":"RSA","kid":"88483727556929326703309904351185815489","alg":"ES256","n":"ie0IKvKLd7Y3izHcZemdDsVVXg5QtWtGF7XEkILnn66R2\_3a30DikqV409OVL7Hv0ElACgCaBLEgZeGHTcdLE1xxDTna8MMBnBNuMVghvFERCKh8uzpxlQsfcnFd5IFdJWj1x5Tscetrow6lA3h5zYx0rF5TkZzC4DclxgDmITRam0dsHBxr3uk9m9YYBz2mX0ehjY0px7vIo7hZH2J3gODEPorIZkk3x8GPdlaA4P9OFAO4au9-zcVQop9vLirxdwDedk2p-F9GP6UiQC9V2LTWqkVw\_oPBf9Rlh8Qdi19jA8SeCfzAxJZYlbOTK8dYAFAVEFsvXCFvdaxQefwWFw","e":"AQAB"}
その他のパラメーターの設定は、一般的な API の設定と同じであり、記載しません。
API を作成したり、API を変更したりしても、設定された KeyId および publicKey は、API の公開後にのみ有効になります。
サービス API の場合、Token に該当するパラメーターを設定する必要があります。
上図のとおり、Token に該当するパラメーターは、Consumer が API を呼び出すときに id_token に送信されるパラメーターです。 API Gateway は、このパラメーターを識別、認証、および解決します。
入力パラメーター定義領域では、該当するパラメーターを定義する必要があります。 それ以外の場合は、下図のとおり、エラーメッセージが表示されます。
- カスタム システム パラメーターの設定: サービス API は、API バックエンドサーバーの定義タブでカスタム システム パラメーターの設定を有効化します。下図は一例です。
AS によって生成された id_token に Consumer の userId が含まれる場合、Consumer の送信した id_token から解決された userId が Provider に送信されます。 カスタム システム パラメーターの設定方法は、システム パラメーターの設定方法と似ています。
上記の 3 点以外に、API のその他の設定を定義する方法は、前のセクションで説明した内容と同じであるため、ここでは説明しません。