前書き
ASP.NET Core で作成したウェブサイトに Sign in WIth Apple を組み込む必要があったので、調べたついでに導入手順を書き残します。
需要があるかわかりませんが、GitHub にサンプルもあげておきます。
https://github.com/Yuki0928/SignInWIthAppleSample
ASP .NET Core では Facebook、Twitter、Google、Microsoft などの外部プロバイダーの認証を非常に簡単にアプリに組み込めるのですが、Sign in with Apple は勝手が違うところがあり少し手間でした。
作業環境
Windows 10
Visual Studio 2019
Apple 開発者ポータルでの事前準備
アップルのヘルプなどを参考に Sign in with Apple を使用する準備を行います。
https://help.apple.com/developer-account/#/devde676e696
主な作業は3つです。
- App ID の作成
- Service ID の作成
- Private Key の作成
個人的にはヘルプは少々わかりづらかったので、こちらの記事を参考に準備を行いました。
https://developer.okta.com/blog/2019/06/04/what-the-heck-is-sign-in-with-apple
ドメインと認証後のコールバック URL の登録 について
今回はローカルで動作確認を行うため、example.com と https://example.com:5001/signin-appleを登録し、hosts に 127.0.0.1 example.com のレコードを登録しました。
localhost で登録できればいいんですが、ちょっと面倒ですね。
ASP.NET Core Web アプリケーションを作成と動作確認
Visual Studio を起動して ASP.NET Core Web アプリケーション を作成します。
Web アプリケーション(モデル ビュー コントローラー)を選択します。
Properties から LaunchSettings.json を開きます。
下のほうの applicationUrl の localhost を example.com に書き換えます。
IIS Express の横の小さな三角ボタンを押して、SignInWithAppleSample を選択します。
SignInWithAppleSample ボタンを押します。
Windows ファイアウォールの警告が表示された場合はアクセスを許可します。
https://example.com:5001で ASP.NET Core Web アプリケーションが動いていることが確認できました。このブラウザは一旦閉じます。
Microsoft.AspNetCore.Authentication.OpenIdConnect をインストール
NuGet で Microsoft.AspNetCore.Authentication.OpenIdConnect をインストールします。
TokenGenerator の作成
Model に TokenGenerator クラスを作成します。
TokenGenerator.cs のコードはこちらをコピペして上書きします。
iss、sub、kid、privateKey は自分の情報に書き換えます。(詳しくは後述)
usingSystem;usingSystem.Collections.Generic;usingSystem.IdentityModel.Tokens.Jwt;usingSystem.Linq;usingSystem.Security.Claims;usingSystem.Security.Cryptography;usingSystem.Threading.Tasks;usingMicrosoft.IdentityModel.Tokens;namespaceSignInWithAppleSample.Models{publicstaticclassTokenGenerator{publicstaticstringCreateNewToken(){conststringiss="TeamID をいれます";conststringsub="ServiceID をいれます";conststringkid="KeyID をいれます";conststringprivateKey="PrivateKey をいれます";varcngKey=CngKey.Import(Convert.FromBase64String(privateKey),CngKeyBlobFormat.Pkcs8PrivateBlob);varhandler=newJwtSecurityTokenHandler();vartoken=handler.CreateJwtSecurityToken(issuer:iss,audience:"https://appleid.apple.com",subject:newClaimsIdentity(newList<Claim>{newClaim("sub",sub)}),expires:DateTime.UtcNow.AddMinutes(5),issuedAt:DateTime.UtcNow,notBefore:DateTime.UtcNow,signingCredentials:newSigningCredentials(newECDsaSecurityKey(newECDsaCng(cngKey)){KeyId=kid},SecurityAlgorithms.EcdsaSha256));returnhandler.WriteToken(token);}}}
TeamID と ServiceID は Apple の開発者ポータルから取得します。
KeyID とPrivateKey は開発者ポータルで Key を発行したときに AuthKey_xxxxxxxxxx.p8
というファイルをダウンロードしているはずですのでそちらから取得します。
KeyID は上記のファイル名の xxxxxxxxxx の部分です。
PrybateKey はファイル内の文字列の改行を削除して1行にしたものを入れます。
先頭の -----BEGIN PRIVATE KEY-----
と末尾の -----END PRIVATE KEY-----
も削除してください。
Sign in with Apple を組み込む
using を追加します。
usingSystem.Net.Http;usingMicrosoft.AspNetCore.Authentication.Cookies;usingMicrosoft.AspNetCore.Authentication.OpenIdConnect;usingMicrosoft.IdentityModel.Protocols.OpenIdConnect;usingMicrosoft.IdentityModel.Tokens;usingSignInWithAppleSample.Models;
ConfigureServices メソッド を以下のように書き換えます。
ServiceID は先ほどと同じものをいれます。
publicvoidConfigureServices(IServiceCollectionservices){services.AddControllersWithViews();services.AddAuthentication(options=>{options.DefaultScheme=CookieAuthenticationDefaults.AuthenticationScheme;options.DefaultChallengeScheme=OpenIdConnectDefaults.AuthenticationScheme;}).AddCookie().AddOpenIdConnect(asyncoptions=>{options.ClientId="ServiceID をいれます";options.CallbackPath="/signin-apple";options.SignInScheme=CookieAuthenticationDefaults.AuthenticationScheme;options.ResponseType=OpenIdConnectResponseType.Code;options.Scope.Clear();options.Configuration=newOpenIdConnectConfiguration{AuthorizationEndpoint="https://appleid.apple.com/auth/authorize",TokenEndpoint="https://appleid.apple.com/auth/token",};options.Events.OnAuthorizationCodeReceived=context=>{context.TokenEndpointRequest.ClientSecret=TokenGenerator.CreateNewToken();returnTask.CompletedTask;};options.TokenValidationParameters.ValidIssuer="https://appleid.apple.com";varjwks=awaitnewHttpClient().GetStringAsync("https://appleid.apple.com/auth/keys");options.TokenValidationParameters.IssuerSigningKeys=newJsonWebKeySet(jwks).Keys;options.ProtocolValidator.RequireNonce=false;});}
Configure メソッドに app.UseAuthentication();
を追加します。
publicvoidConfigure(IApplicationBuilderapp,IWebHostEnvironmentenv){if(env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Home/Error");// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.app.UseHsts();}app.UseHttpsRedirection();app.UseStaticFiles();app.UseRouting();app.UseAuthorization();app.UseAuthentication();// この1行を追加app.UseEndpoints(endpoints=>{endpoints.MapControllerRoute(name:"default",pattern:"{controller=Home}/{action=Index}/{id?}");});}
適当な場所に SignInWithApple メソッドを追加します。
publicIActionResultSignInWithApple(){returnChallenge(newAuthenticationProperties{RedirectUri="/"},OpenIdConnectDefaults.AuthenticationScheme);}
末尾に以下のコードを書き足します。
@if(User.Identity.IsAuthenticated){@User.Claims.First(x=>x.Type.Contains("nameidentifier")).Value}else{@Html.ActionLink("Sign in With Apple でサインインする","SignInWithApple")}
以上で導入は一旦完了です。
ログアウト処理を書いていませんが、Sign in with Apple だからといって変わったことはないのでここでは割愛します。
Sign in With Apple の動作確認
最初の動作確認と同様に Web アプリケーションをデバッグ実行します。
Sign in With Apple でサインインする のリンクをクリックします。
サインインすると元の画面に戻ります。
Apple から取得したユーザーの ID が表示されます。
これでアプリやゲームに Sign in With Apple を組み込めますね!