Azure Mobile Services の .NET 向けの最新機能
このポストは、7 月 28 日に投稿した Azure Mobile Services .NET Updates (著者: Henrik) の翻訳です。
Azure Mobile Services の .NET (英語) 向けの新機能をリリースしました。
- ASP.NET Web API CORS を使用した CORS のサポートにより、CORS ポリシーをサービス、コントローラー、アクションのレベルごとに指定できます。
- 拡張可能な認証モデルにより、Mobile Services のクライアントでどの認証機構を利用可能にするかをコントロールできます。たとえば、標準でサポートされている Azure Active Directory、Twitter、Facebook、Google、Microsoft アカウントに追加して、またはそれらの代わりに、独自の認証機構を使用することができます。
- サーバー側のフローを使用した Azure Active Directory 認証のサポートにより、クライアント認証がよりシンプルになります。
Azure Mobile Services の .NET での開発が初めての方は、こちらの概説をお読みになってください。Azure Mobile Services の情報全般はこちら (英語) にあります。
ご意見、ご質問などございましたら、MSDN フォーラムまたは Twitter (@frystyk) からいつでもお寄せください。
更新プログラムの入手
Mobile Services の QuickStart と Visual Studio プロジェクトのどちらで始める場合も、NuGet (英語) から更新プログラム (Version 1.0.342) を入手してください。Visual Studio プロジェクトの NuGet Package Manager に移動し、[Updates] を選択して検索ウィンドウに「windowszure.mobileservices」と入力すると、次のようになります。
「windowsazure.mobileservices」を検索して、Mobile Services の更新プログラムをインストールすれば完了です。これらのパッケージには必要な他の更新プログラムが含まれるので、他のパッケージを手動で更新する必要はありません。
CORS のサポート
最初に紹介する新機能は、ASP.NET Web API CORS NuGet パッケージ (英語) で提供されているサポートを利用した CORS の標準サポートです。EnableCorsAttribute を使用した設定の制御方法など、ASP.NET Web API の CORS のわかりやすい説明については、ブログ記事「ASP.NET Web API 2 における CORS サポート」をご覧ください。
既定で Azure Mobile Services は、CORS リクエストを一切許可しないという既定のポリシーで CORS を有効化します。許可するドメインのリストを設定する場合は、ポータルから行うか、MS_CrossDomainOrigins アプリケーション設定を使用して、次のようにカンマ区切りでドメインを設定します。
<add key="MS_CrossDomainOrigins" value="https://testhost, https://sample" />
これにより、https://testhost と https://sample の 2 か所から、HTTP メソッドと HTTP ヘッダーを使用してアクセス可能になります。
サービスの構成に使用する ConfigOptions インスタンスを修正して、全く別の既定のポリシーを設定することも可能です。次のように設定します。
public static class WebApiConfig
{
public static void Register()
{
// このクラスを使用して Mobile Services の構成オプションを設定
ConfigOptions options = new ConfigOptions();
options.CorsPolicy =
new System.Web.Http.Cors.EnableCorsAttribute("*", "*", "*");
...
}
}
従来どおり、特定の CORS ポリシーをコントローラー別やアクション別に設定できるので、柔軟に CORS を利用することができます。
拡張可能な認証モデル
Azure Mobile Services は、Azure Active Directory、Twitter、Facebook、Google、Microsoft アカウントに対応した共通の認証モデルを提供しています。これらのログイン プロバイダーに独自の認証方法を追加したり、既定のプロバイダーを変更または削除したりすることができるようになりました。
たとえば、「カスタム認証を利用する (英語)」で説明しているように、カスタム認証のサポートを追加できます。また、他の OWIN 認証プロバイダーを利用して、ID プロバイダーのサポートを追加することも可能です。ここからは、LoginProvider を作成するための 4 つの手順として、Owin.Security.Providers NuGet パッケージ (英語) を使用して LinkedIn (英語) のサポートを追加する方法をご紹介します。
最初に、LinkedIn ミドルウェアを対象として次の 3 つのタスクを実行する LoginProvider の実装を作成します。
- LinkedIn OWIN ミドルウェアを登録して認証に参加
- LinkedIn から取得したアクセス トークンをシリアル化
- アクセス トークンを逆シリアル化
コードは次のようになります。
public class LinkedInLoginProvider : LoginProvider
{
internal const string ProviderName = "LinkedIn";
public LinkedInLoginProvider(IServiceTokenHandler tokenHandler)
: base(tokenHandler)
{
}
public override string Name
{
get { return ProviderName; }
}
public override void ConfigureMiddleware(IAppBuilder appBuilder,
ServiceSettingsDictionary settings)
{
LinkedInAuthenticationOptions options = new LinkedInAuthenticationOptions
{
ClientId = settings["LinkedInClientId"],
ClientSecret = settings["LinkedInClientSecret"],
AuthenticationType = this.Name,
Provider = new LinkedInLoginAuthenticationProvider()
};
appBuilder.UseLinkedInAuthentication(options);
}
public override ProviderCredentials CreateCredentials(
ClaimsIdentity claimsIdentity)
{
Claim name = claimsIdentity.FindFirst(ClaimTypes.NameIdentifier);
Claim providerAccessToken = claimsIdentity
.FindFirst(ServiceClaimTypes.ProviderAccessToken);
LinkedInCredentials credentials = new LinkedInCredentials
{
UserId = this.TokenHandler.CreateUserId(this.Name, name != null ?
name.Value : null),
AccessToken = providerAccessToken != null ?
providerAccessToken.Value : null
};
return credentials;
}
public override ProviderCredentials ParseCredentials(JObject serialized)
{
return serialized.ToObject<LinkedInCredentials>();
}
}
ローカルの Web.config ファイルに直接設定可能な、新しい 2 つのカスタム アプリケーション設定 (LinkedInClientId と LinkedInClientSecret) を使用して、LinkedIn のクライアント ID とシークレットを設定します。これについては後ほど説明します。
次に、LinkedIn アクセス トークンが ID のクレームとして追加されるようにします。
public class LinkedInLoginAuthenticationProvider : LinkedInAuthenticationProvider
{
public override Task Authenticated(LinkedInAuthenticatedContext context)
{
context.Identity.AddClaim(
new Claim(ServiceClaimTypes.ProviderAccessToken, context.AccessToken));
return base.Authenticated(context);
}
}
3 つ目の手順として、アクセス トークンをパブリック プロパティとして持つ ProviderCredentials クラスを定義します。
public class LinkedInCredentials : ProviderCredentials
{
public LinkedInCredentials()
: base(LinkedInLoginProvider.ProviderName)
{
}
public string AccessToken { get; set; }
}
最後に、新しい LoginProvider をサービスに登録します。それには、WebApiConfig クラスの Register メソッドを使用します。
public static class WebApiConfig
{
public static void Register()
{
ConfigOptions options = new ConfigOptions();
options.LoginProviders.Add(typeof(LinkedInLoginProvider));
HttpConfiguration config = ServiceConfig.Initialize(
new ConfigBuilder(options));
...
}
}
クライアント ID とクライアント シークレットのアプリケーション設定をローカルの web.config ファイルに追加します。
<add key="LinkedInClientId" value="your value here" />
<add key="LinkedInClientSecret" value="your value here" />
これで、サービスを Visual Studio でローカルで実行できます。ブラウザーで /login/linkedin にアクセスすると、次のようなページにリダイレクトされます。
LinkedIn 資格情報を使用してログインすると、最終的に https://localhost:31475/login/done#token=<token> という URI にリダイレクトされます。クライアントから新しい LoginProvider を利用するには、“LinkedIn” という文字列を使用して参照します。
private async Task AuthenticateAsync()
{
while (user == null)
{
string message;
try
{
user = await App.MobileService.LoginAsync("linkedin");
message = string.Format("You are now logged in - {0}", user.UserId);
}
catch (InvalidOperationException)
{
message = "You must log in. Login Required";
}
var dialog = new MessageDialog(message);
dialog.Commands.Add(new UICommand("OK"));
await dialog.ShowAsync();
}
}
Azure Active Directory 認証
Azure Mobile Services の .NET での開発では、既に Active Directory Authentication Library シングル サインオンによる認証 (英語) がサポートされていますが、Active Directory Authentication Library がサポートしていないクライアント プラットフォームに必要なサーバー フローはサポートされていませんでした。
既定の Azure Active Directory LoginProvider では、Active Directory Authentication Library が提供するクライアント側のフローがサポートされていますが、このライブラリをサポートするクライアント プラットフォームでしか機能しません。
Azure Mobile Services がサポートするあらゆるクライアントに対応可能なサーバー側のフローを実現するには、最初に Microsoft Azure Mobile Services の .NET バックエンド向けセキュリティ拡張機能 (英語) の NuGet プレビュー パッケージをサーバー プロジェクトにインストールします。次に、WebApiConfig クラスの Register メソッドで以下を実行して、既定の Azure Active Directory LoginProvider を置き換えます。
public static class WebApiConfig
{
public static void Register()
{
ConfigOptions options = new ConfigOptions();
options.LoginProviders.Remove(typeof(AzureActiveDirectoryLoginProvider));
options.LoginProviders.Add(typeof(AzureActiveDirectoryExtendedLoginProvider));
HttpConfiguration config = ServiceConfig.Initialize(
new ConfigBuilder(options));
...
}
}
AzureActiveDirectoryExtendedLoginProvider クラスは、クライアントとサーバー両方のフローをサポートしており、クライアント プラットフォームに最適な機能を使用できます。
一般的な Mobile Services 認証モデルの詳細については、「Mobile Services で認証を利用する (英語)」という資料を参照してください。
これで以上です。今回紹介した機能が皆様のお役に立ちますと幸いです。他に興味がある機能がありましたらお知らせください。
それでは .NET での開発をお楽しみください!
Henrik