API認証
すべてのAPIリクエストは、Authorizationヘッダーを通じて認証する必要があります。NTT CPaaS APIでは、以下の認証方法をご利用いただけます:
- HTTPベーシック認証
- APIキー
- IBSSOトークン
- OAuth 2.0
現在の技術スタックとセキュリティ要件レベルに合わせて、お好みの方法を選択してください。これらの方法の多くは中間者攻撃に対して脆弱であるため、暗号化された接続やSSLなどの他のセキュリティ対策と組み合わせて導入することをお勧めします。
発生しうる潜在的な問題について確認したい時は、トラブルシューティングを行うか、NTT CPaaSのサポートチームまでお問い合わせください。
ベーシック
ベーシック認証は、すべてのAPIリクエストにユーザー名とパスワードを送信することで機能します。通常、この方法はAPIキーが利用できない場合に使用されます。例えば、APIキーを生成するAPIメソッドでは、ベーシック認証によって認証を行うことができます。
ベーシック認証は、暗号化された資格情報を元の値に戻すのが未だに容易なため、最も推奨されていない方法です。ベージック認証を使用してサーバーへのアクセスを制限する方法については、HTTP認証リソース (opens in a new tab) について詳述しているドキュメントをご参照ください。
この方法に関するいくつかの重要な事実を次に示します:
- HTTPプロトコル自体に組み込まれています
- 資格情報は、Base64形式 (例えば、RFC2045-MIME (opens in a new tab) バリアントを使用する場合など) でエンコードし、コロン (:) で区切る必要があります
- エンコードされた資格情報は、ヘッダーの
Basicの後に追加されます
例 - HTTPクライアント
NTT CPaaS APIのクライアントライブラリ (opens in a new tab) のいずれかをご利用の場合、資格情報を手動でエンコードする必要はありません。クライアントオブジェクトのインスタンスを作成する際に、ユーザー名とパスワードを指定するだけで済みます。
curl -L -g -X GET 'https://{baseUrl}/sms/2/text/advanced' /
-H 'Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
String auth = username + ":" + password;
String encoded = Base64.getEncoder().encodeToString(auth.getBytes("UTF-8"));
String messageText = "This is test message sent using OkHttpClient and Basic auth";
String jsonBody = String.format(
"{\"messages\":[{\"from\":\"%s\",\"destinations\":[{\"to\":\"%s\"}],\"text\":\"%s\"}]}",
SENDER, PHONE_NUMBER, messageText);
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonBody);
Request request = new Request.Builder()
.url(BASE_URL + "/sms/2/text/advanced")
.addHeader("Authorization", "Basic " + encoded)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.post(requestBody)
.build();
OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
Response response = httpClient.newCall(request).execute();
System.out.println(response.body().string());
string username = "USERNAME";
string password = "PASSWORD";
string concatenated = $"{username}:{password}";
string encoded = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(concatenated));
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("BASE_URL");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", encoded);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
例 - APIクライアントライブラリ
NTT CPaaS APIのクライアントライブラリ (opens in a new tab) のいずれかをご利用の場合、上記の通り、資格情報を手動でエンコードする必要はありません。以下の例で示すように、クライアントオブジェクトのインスタンスを作成する際に、ユーザー名とパスワードを指定するだけで済みます。
var configuration = new Configuration()
{
BasePath = "BASE_URL",
Username = "USERNAME",
Password = "PASSWORD"
};
ベーシック認証のAPIスコープ
ベーシック認証に関連するAPIスコープの詳細については、ユーザーロールとAPIスコープ について詳述しているセクションをご参照ください。
APIキーヘッダー
APIキーとは、クライアントがAPIコールを送信する際に提示するアクセストークンのことです。これはアクセスをセキュアに保つための簡便な方法であり、そのためREST APIで最も広く利用されている認証方式となっています。キーは、クエリ文字列またはリクエストヘッダーとして送信できます。アカウントを作成 すると、自動的にAPIキーが割り当てられます。より多くのキーを生成したり、既存のキーを管理したりしたい時は、NTT CPaaSのAPIキー管理 (opens in a new tab) ページをご参照ください。
この方法に関するいくつかの重要な事実を次に示します:
- APIキーは、専用のAPIメソッドを呼び出すことで生成できます
- キーはいつでも無効化できるため、複数のアプリケーションまたはユースケース間でAPIへのアクセス権限を分離する際に便利です
- NTT CPaaSのAPIキーには、最終的に無効になる有効期限が事前定義されています
例 - HTTPクライアント
以下の例では、クライアントライブラリ (opens in a new tab) をご利用の際に、APIキーの認証方法をいかに指定するかを示しています。
curl -L -g -X GET 'https://{baseUrl}/sms/2/text/advanced' /
-H 'Authorization: App 003026abc133714df1834b8638bb496e-8f4b3d9a-e931-478d-a994-28a725159ab9'
Request request = new Request.Builder()
.url("BASE_URL" + "/sms/2/text/advanced")
.addHeader("Authorization", "App " + apiKey)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.post(requestBody)
.build();
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("BASE_URL");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("App", "API_KEY");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
例 - APIクライアントライブラリ
以下の例は、APIキー認証を使用してHTTPリクエストを作成する方法を示しています。なお、このリクエストは、ベーシック認証リクエストを使用する場合よりもはるかに簡単です。
ApiClient apiClient = ApiClient.forApiKey(ApiKey.from(API_KEY))
.withBaseUrl(BaseUrl.from(BASE_URL))
.build();
var configuration = new Configuration()
{
BasePath = "BASE_URL",
ApiKeyPrefix = "App",
ApiKey = "API_KEY"
};
APIキーのAPIスコープ
APIスコープの詳細については、APIスコープ について詳述しているセクションをご参照ください。
IBSSOトークンヘッダー
IBSSOトークンはセッションベースであるため、トークンの有効期間は短期間に留まります。これにより、最終的にはこの方法の安全性が高まりますが、認証を有効に保つためには、より多くのメンテナンスが必要となります。
通常、この種の認証は、システム全体で複数のサインインを回避したいシングルサインオンのシナリオで利用されます。また、機密データを様々な企業システムに分散させることなく、一元的に処理する必要があるシナリオにも有用な場合があります。
この方法に関するいくつかの重要な事実を次に示します:
- すべてのAPIリクエストは、セッショントークン (opens in a new tab)で認証されます
- デフォルトでは、IBSSOトークンは60分後に失効するため、その後は新しいトークンを作成する必要があります
- 新しいトークンを作成したいが、前のトークンの有効期限がまだ切れていない場合は、最初にセッションを破棄 (opens in a new tab)する必要があります
- 専用のAPIコール (opens in a new tab)でセッションの長さを短縮できます
IBSSOトークンの使い方
- セッションエンドポイントを作成するコールを送信し、レスポンスからトークンを取得します。
- 後続のすべてのコールのAuthorizationヘッダーに
IBSSOとトークンを含めます:Authorization: IBSSO 2f9b4d31-2d0d-49a8-85f0-9b862bdca394 - 必要に応じて、セッションを破棄して、セッションの有効期間を調整することもできます。デフォルトでは、セッションは60分後に失効します。
HTTPリクエスト
IBSSOトークンの取得
Create session (セッション作成) エンドポイントを呼び出して、セッションを作成します。レスポンスには、 Send SMS (SMS送信) (opens in a new tab) エンドポイントといったの他のAPIエンドポイントへのリクエストのHTTPヘッダーで使用できるトークンが含まれます。
private static class IbssoResponse {
public IbssoResponse() {
super();
}
@JsonProperty("token")
public String token;
@JsonGetter("token")
public String getToken() {
return token;
}
@JsonSetter("token")
public void setToken(String token) {
this.token = token;
}
}
String jsonBody = String.format("{\"username\":\"%s\",\"password\":\"%s\"}", "USERNAME", "PASSWORD");
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonBody);
Request request = new Request.Builder()
.url("BASE_URL" + "/auth/1/session")
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.post(requestBody)
.build();
OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
Response response = httpClient.newCall(request).execute();
String responseBody = response.body().string();
System.out.println(responseBody);
IbssoResponse ibssoResponse = new ObjectMapper().readValue(responseBody, IbssoResponse.class);
return ibssoResponse.token;
public class IbssoResponse
{
[System.Text.Json.Serialization.JsonPropertyName("token")]
public string Token { get; set; }
}
string username = "USERNAME";
string password = "PASSWORD";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("BASE_URL");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string body = $@"
{{
""username"": ""{username}"",
""password"": ""{password}""
}}";
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, "/auth/1/session");
httpRequest.Content = new StringContent(body, System.Text.Encoding.UTF8, "application/json");
var response = client.SendAsync(httpRequest).GetAwaiter().GetResult();
var responseContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var responseObject = JsonSerializer.Deserialize(responseContent);
return responseObject.Token;
例 - HTTPクライアント
以下の例は、HTTPリクエストを準備する方法を示しています。この方法はAPIキー認証とほぼ同じですが、ヘッダーには App の代わりに IBBSO を使用します。
private static class IbssoResponse {
public IbssoResponse() {
super();
}
@JsonProperty("token")
public String token;
@JsonGetter("token")
public String getToken() {
return token;
}
@JsonSetter("token")
public void setToken(String token) {
this.token = token;
}
}
String jsonBody = String.format("{\"username\":\"%s\",\"password\":\"%s\"}", "USERNAME", "PASSWORD");
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonBody);
Request request = new Request.Builder()
.url("BASE_URL" + "/auth/1/session")
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.post(requestBody)
.build();
OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
Response response = httpClient.newCall(request).execute();
String responseBody = response.body().string();
System.out.println(responseBody);
IbssoResponse ibssoResponse = new ObjectMapper().readValue(responseBody, IbssoResponse.class);
return ibssoResponse.token;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("BASE_URL");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("IBSSO", "TOKEN");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
例 - APIライブラリ
NTT CPaaSのAPIクライアントライブラリ (opens in a new tab) を使用する場合は、APIキー認証と同じ要素が必要ですが、App の代わりに IBBSO を使用します。
var configuration = new Configuration()
{
BasePath = "BASE_URL",
ApiKeyPrefix = "IBSSO",
ApiKey = "TOKEN"
};
OAuth 2.0
この認証方式は最も安全な選択肢であり、事実上の業界標準となっています。IBSSOトークンを利用する場合と同様に、別のエンドポイントから取得したアクセストークンを使用することになります。
この方法に関するいくつかの重要な事実を次に示します:
- レスポンスで返されたアクセストークンは、同じレスポンスで秒単位で指定された制限時間内に期限切れになります。
- NTT CPaaSは、リソースサーバーおよび認証サーバーの両方の役割を果たします。
- トークンの有効期限が切れたら、新しいトークンを作成する必要があります。トークンの自動取得は行われません。
詳細については、公式の OAuth 2.0 (opens in a new tab) 仕様をご参照ください。
OAuth 2.0の使い方
- 別のエンドポイント (opens in a new tab)からアクセストークンと有効期限を取得するためにコールを送信します。
- トークンの有効期限が切れるまで、後続のすべてのコールのAuthorizationヘッダーに
Bearerとトークンを含めます。Authorization: Bearer eyJraWQiOiI5d29rWGRoSSIsInR5cCI6IkpXVCIsImFsZyI6IkhTMjU2In0.eyJzdWIiOiJERDIwMjAiLCJpc3MiOiJpbmZvYmlwLmNvbSIsImV4cCI6MTYzMzAwNDQwNiwiaWF0IjoxNjMzMDAwODA2LCJqdGkiOiJiMmJmODgyMS01OTcxLTRiOTMtYWVmNy0zM2QwMDNkMjIxNjcifQ.KvIIOmCKJETiB6xKOqBxvZYnYOa8RAulYhChBEmI4Os
HTTPリクエスト
OAuthトークンの取得
IBSSOトークンと同様に、APIコールを行う前に、まずトークンを取得する必要があります。
private static class OauthResponse {
public OauthResponse() {
super();
}
@JsonProperty("access_token")
private String accessToken;
@JsonProperty("expires_in")
private String expiresIn;
@JsonGetter("access_token")
public String getAccessToken() {
return accessToken;
}
@JsonSetter("access_token")
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
@JsonGetter("expires_in")
public String getExpiresIn() {
return expiresIn;
}
@JsonSetter("expires_in")
public void setExpiresIn(String expiresIn) {
this.expiresIn = expiresIn;
}
}
HttpPost post = new HttpPost(BASE_URL + "/auth/1/oauth2/token");
List nvps = new ArrayList();
nvps.add(new BasicNameValuePair("client_id", username));
nvps.add(new BasicNameValuePair("client_secret", password));
nvps.add(new BasicNameValuePair("grant_type", "client_credentials"));
post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(post);
System.out.println(response.getStatusLine());
String responseJson = EntityUtils.toString(response.getEntity());
System.out.println(responseJson);
OauthResponse oauthResponse = new ObjectMapper().readValue(responseJson, OauthResponse.class);
return oauthResponse.accessToken;
public class OauthResponse
{
[System.Text.Json.Serialization.JsonPropertyName("expires_in")]
public int ExpiresIn { get; set; }
[System.Text.Json.Serialization.JsonPropertyName("access_token")]
public string AccessToken { get; set; }
}
string username = "USERNAME";
string password = "PASSWORD";
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("BASE_URL");
var dict = new Dictionary();
dict.Add("client_id", username);
dict.Add("client_secret", password);
dict.Add("grant_type", "client_credentials");
HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Post, "/auth/1/oauth2/token");
httpRequest.Content = new FormUrlEncodedContent(dict);
var response = client.SendAsync(httpRequest).GetAwaiter().GetResult();
var responseContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var responseObject = JsonSerializer.Deserialize(responseContent);
var accessToken = responseObject.AccessToken;
例 - HTTPクライアント
以下の例は、ヘッダーを含むHTTPクライアントリクエストを準備する方法を示しています。
Request request = new Request.Builder()
.url("BASE_URL" + "/sms/2/text/advanced")
.addHeader("Authorization", "Bearer " + accessToken)
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.post(body)
.build();
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("BASE_URL");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "ACCESS_TOKEN");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
例 - APIライブラリ
以下の例は、ヘッダーを含むHTTPリクエストを準備する方法を示しています。
var configuration = new Configuration()
{
BasePath = "BASE_URL",
ApiKeyPrefix = "Bearer",
ApiKey = "ACCESS_TOKEN"
};エラー
通常、ユーザー名またはパスワードが見つからないか無効な場合、レスポンスには401 UnauthorisedがHTTPステータスコードとして表示されます。
{
"requestError": {
"serviceException": {
"messageId": "UNAUTHORIZED",
"text": "Invalid login details"
}
}
}
ライブラリの例外
いずれかのライブラリ (opens in a new tab) を使用する場合は、必ずAPI例外を処理するようにしてください。
try {
SmsResponse smsResponse = sendSmsApi.sendSmsMessage(smsMessageRequest);
} catch (ApiException apiException) {
apiException.getCode();
apiException.getResponseHeaders();
apiException.getResponseBody();
}
try
{
var result = api.SendSmsMessage(smsRequest);
}
catch(ApiException apiException)
{
var errorCode = apiException.ErrorCode;
var errorContent = apiException.ErrorContent;
}