Windows プッシュ通知サービス (WNS) に対して認証する方法 (Windows ランタイム アプリ)
[ この記事は、Windows ランタイム アプリを作成する Windows 8.x および Windows Phone 8.x 開発者を対象としています。Windows 10 向けの開発を行っている場合は、「最新のドキュメント」をご覧ください]
ここでは、Windows プッシュ通知サービス (WNS) に対してクラウド サーバーの認証を行い、WNS からアクセス トークンを受け取る方法について説明します。
必要条件
- Windows ストア開発者アカウント。
- 登録する Windows ストア アプリ。
- タイルと通知に関する用語と概念および XML についての実用的知識。
- プッシュ通知と WNS の概念、要件、動作の知識。
手順
ステップ 1: アプリをダッシュボードに登録する
WNS を使って通知を送るには、アプリを登録する必要があります。アプリの登録にはダッシュボードを使います。ダッシュボードは、Windows ストア アプリの提出、認定、管理のための開発者ポータルです。アプリをダッシュボードを通じて登録すると、クラウド サービスが WNS に対して自身の認証を行う際に使う資格情報 (パッケージ セキュリティ識別子 (SID) と秘密鍵) が提供されます。
アプリを登録するには、次の手順を実行します。
Windows デベロッパー センターの Windows ストア アプリのページに移動し、Microsoft アカウントを使ってサインインします。
サインインしたら、[ダッシュボード] リンクをクリックします。
ダッシュボードで、[アプリの提出] を選びます。
[アプリの提出] ページで、[アプリの名前] をクリックします。
アプリに一意の名前を付けます。名前を入力し、[アプリの名前の予約] をクリックします。名前が使用できる場合は、アプリ用にその名前が予約されます。アプリの名前の予約が正常に完了した時点で、他の詳しい情報も変更できるようになります。
ステップ 2: アプリの ID 値を取得する
アプリの名前を予約したときに、Windows ストアによって関連する資格情報が作られます。また、アプリのマニフェスト ファイル (package.appxmanifest) に示す必要がある関連する ID 値 (名前と発行元) も割り当てられます。Windows ストアにアプリを既にアップロードしている場合は、これらの ID 値がマニフェストに自動的に追加されています。アプリをアップロードしていない場合は、ID 値をマニフェストに手動で追加する必要があります。
[サービス] リンクをクリックします。
[サービス] ページで、[Microsoft Azure のモバイル サービス] セクションの下にある [Live サービス] リンクをクリックします。
[プッシュ通知と Live Connect サービスの情報] ページで、次に示す [アプリの識別] を選びます。
[アプリの識別] ページでは、アプリのマニフェストに含める identity 要素が提供されます。テキスト エディターでマニフェストを開き、その要素を、ページを示すものとして追加してください。
ステップ 3: アプリの資格情報を取得する
同じ [アプリの識別] ページの下部にある [サービスの認証] リンクをクリックします。
[サービスの認証] ページでは、セキュリティ識別子とクライアント シークレットが提供されます。このアプリにプッシュ通知を送るには、クラウド サービスでこれらの資格情報を正確に使う必要があります。別のクラウド サービスの資格情報を使って、このアプリに通知を送ることはできません。また、これらの資格情報を使って、別のアプリに通知を送ることもできません。
注 このページを使って、新しい資格情報を生成することもできます。
SID とクライアント シークレットをクラウド サーバーにアップロードします。
重要 クラウド サービスで SID とクライアント シークレットを保存し、この情報にアクセスするときは、セキュリティで保護された方法を使う必要があります。この情報の漏洩や盗難が発生すると、開発者の知らない間に攻撃者が無許可でユーザーに通知を送信できるようになるおそれがあります。
ステップ 4: クラウド サーバーの資格情報を WNS に送信する
クラウド サービスからは、HTTPS 認証要求で資格情報 (SID とクライアント シークレット) を提示します。この認証要求では、"application/x-www-for-urlencoded" という形式を使います。
以下は、サンプルの HTTPS 認証要求を示しています。grant_type にパッケージ SID と秘密鍵が含まれています。このコードをコピーする場合は、"client_id" フィールドを実際のパッケージ SID に置き換え、"client_secret" フィールドを実際の秘密鍵に置き換えてください。構文については、「プッシュ通知サービスの要求ヘッダーと応答ヘッダー」を参照してください。
POST /accesstoken.srf HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Host: https://login.live.com
Content-Length: 211
grant_type=client_credentials&client_id=ms-app%3a%2f%2fS-1-15-2-2972962901-2322836549-3722629029-1345238579-3987825745-2155616079-650196962&client_secret=Vex8L9WOFZuj95euaLrvSH7XyoDhLJc7&scope=notify.windows.com
WNS は、認証要求に対する応答をサーバーに送信します。応答コードが "200 OK" であれば、認証が成功し、応答にアクセス トークンが含まれています。クラウド サーバーはこのアクセス トークンを保存し、期限切れになるまで、送信するすべての通知で使う必要があります。
以下は、成功した認証に対する WNS 応答の例を示しています。
HTTP/1.1 200 OK
Cache-Control: no-store
Content-Length: 422
Content-Type: application/json
{
"access_token":"EgAcAQMAAAAALYAAY/c+Huwi3Fv4Ck10UrKNmtxRO6Njk2MgA=",
"token_type":"bearer"
}
次の例は、認証要求を送信し、応答を受信するために必要なコードを示しています。この例のコードは、独自のクラウド サーバー コードに直接コピーできます。ただし、次のディレクティブが含まれている場合に限ります。
using System.Runtime.Serialization.Json;
using System.Runtime.Serialization;
using System.IO;
[DataContract]
public class OAuthToken
{
[DataMember(Name = "access_token")]
public string AccessToken { get; set; }
[DataMember(Name = "token_type")]
public string TokenType { get; set; }
}
private OAuthToken GetOAuthTokenFromJson(string jsonString)
{
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
{
var ser = new DataContractJsonSerializer(typeof(OAuthToken));
var oAuthToken = (OAuthToken)ser.ReadObject(ms);
return oAuthToken;
}
}
protected OAuthToken GetAccessToken(string secret, string sid)
{
var urlEncodedSecret = HttpUtility.UrlEncode(secret);
var urlEncodedSid = HttpUtility.UrlEncode(sid);
var body =
String.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=notify.windows.com", urlEncodedSid, urlEncodedSecret);
string response;
using (var client = new WebClient())
{
client.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
response = client.UploadString("https://login.live.com/accesstoken.srf", body);
}
return GetOAuthTokenFromJson(response);
}