Web API での SSL の操作
一般的な認証方式の中には、プレーンな HTTP では安全でないものがあります。 具体的には、基本認証とフォーム認証で送信する資格情報が暗号化されません。 安全性を確保するには、これらの認証方式で SSL を使用する必要があります。 さらに、SSL クライアント証明書を使ってクライアントを認証できます。
サーバーでの SSL の有効化
IIS 7 以降で SSL を設定するには:
- 証明書を作成または取得します。 テスト用には、自己署名証明書を作成できます。
- HTTPS バインドを追加します。
詳しくは、IIS 7 で SSL を設定する方法に関する記事をご覧ください。
ローカル テストの場合は、Visual Studio から IIS Express で SSL を有効にできます。 [プロパティ] ウィンドウで [SSL 有効] を [True] に設定します。 [SSL URL] の値を記録しておきます。HTTPS 接続のテストでこの URL を使います。
Web API コント ローラーでの SSL の適用
HTTPS と HTTP の両方のバインドがある場合、クライアントは引き続き HTTP を使ってサイトにアクセスできます。 一部のリソースは HTTP 経由での使用を許可し、他のリソースは SSL を必要にする場合があります。 そのような場合は、アクション フィルターを使って、保護されたリソースには SSL を要求します。 次のコードは、SSL をチェックする Web API 認証フィルターを示しています。
public class RequireHttpsAttribute : AuthorizationFilterAttribute
{
public override void OnAuthorization(HttpActionContext actionContext)
{
if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
{
actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
{
ReasonPhrase = "HTTPS Required"
};
}
else
{
base.OnAuthorization(actionContext);
}
}
}
このフィルターを、SSL を必要とする Web API アクションすべてに追加します。
public class ValuesController : ApiController
{
[RequireHttps]
public HttpResponseMessage Get() { ... }
}
SSL クライアント証明書
SSL では、公開キー基盤証明書を使って認証が提供されます。 サーバーは、クライアントに対してサーバーの認証を行う証明書を提供する必要があります。 クライアントがサーバーに証明書を提供することはあまり一般的ではありませんが、これはクライアントを認証するための 1 つのオプションです。 SSL でクライアント証明書を使うには、署名された証明書をユーザーに配布する方法が必要です。 多くのアプリケーションの種類では、これはよいユーザー エクスペリエンスではありませんが、一部の環境 (エンタープライズなど) では適している場合があります。
長所 | 短所 |
---|---|
- 証明書の資格情報は、ユーザー名とパスワードより強力です。 - SSL では、認証、メッセージの整合性、メッセージの暗号化を備えた完全なセキュリティ保護チャネルが提供されます。 | - ユーザーは、PKI 証明書を取得して管理する必要があります。 - クライアント プラットフォームは、SSL クライアント証明書をサポートする必要があります。 |
クライアント証明書を受け入れるように IIS を構成するには、IIS マネージャーを開いて、次の手順を実行します。
ツリー ビューでサイト ノードをクリックします。
中央のペインで [SSL 設定] 機能をダブルクリックします。
[クライアント証明書] で、次のいずれかのオプションを選びます。
- 受け入れ: IIS はクライアントからの証明書を受け入れますが、必須ではありません。
- 必須: クライアント証明書が必要です。 (このオプションを有効にするには、[SSL を必要とする] も選ぶ必要があります)
ApplicationHost.config ファイルでこれらのオプションを設定することもできます。
<system.webServer>
<security>
<access sslFlags="Ssl, SslNegotiateCert" />
<!-- To require a client cert: -->
<!-- <access sslFlags="Ssl, SslRequireCert" /> -->
</security>
</system.webServer>
SslNegotiateCert フラグは、IIS がクライアントから証明書を受け入れますが、それが必須ではないことを意味します (IIS マネージャーの [受け入れ] オプションと同等)。 証明書を必須にするには、SslRequireCert フラグを設定します。 テストのためには、IIS Express を使って、"Documents\IISExpress\config" にあるローカル applicationhost.Config ファイルでこれらのオプションを設定することもできます。
テスト用のクライアント証明書の作成
テストのために、MakeCert.exe を使ってクライアント証明書を作成できます。 最初に、テスト ルート機関を作成します。
makecert.exe -n "CN=Development CA" -r -sv TempCA.pvk TempCA.cer
Makecert から、秘密キーのパスワードの入力を求められます。
次に、以下のようにして、テスト サーバーの "信頼されたルート証明機関" ストアに証明書を追加します。
- MMC を開きます。
- [ファイル] の [スナップインの追加と削除] を選びます。
- [コンピューター アカウント] を選びます。
- [ローカル コンピューター] を選んで、ウィザードを完了します。
- ナビゲーション ウィンドウで、[信頼されたルート証明機関] ノードを展開します。
- [操作] メニューの [すべてのタスク] をポイントし、[インポート] をクリックして証明書のインポート ウィザードを起動します。
- 証明書ファイル TempCA.cer を参照します。
- [開く] をクリックし、[次へ] をクリックしてウィザードを完了します。 (パスワードをもう一度入力するように求められます)。
次に、最初の証明書によって署名されたクライアント証明書を作成します。
makecert.exe -pe -ss My -sr CurrentUser -a sha1 -sky exchange -n "CN=name"
-eku 1.3.6.1.5.5.7.3.2 -sk SignedByCA -ic TempCA.cer -iv TempCA.pvk
Web API でのクライアント証明書の使用
サーバー側では、要求メッセージで GetClientCertificate を呼び出して、クライアント証明書を取得できます。 クライアント証明書がない場合、このメソッドは null を返します。 それ以外の場合は、X509Certificate2 インスタンスを返します。 このオブジェクトを使って、発行者やサブジェクトなどの情報を証明書から取得します。 その後、この情報を認証や認可に使用できます。
X509Certificate2 cert = Request.GetClientCertificate();
string issuer = cert.Issuer;
string subject = cert.Subject;