♻️

Server Side Blazor + Google 認証 の最小構成メモ

2020/09/26に公開

Visual Studio の Server Side Blazor のプロジェクトテンプレートに Google 認証を追加する。

以下の ASP.NET Core Identity なしの Google 認証を行う。

https://docs.microsoft.com/aspnet/core/security/authentication/social/social-without-identity?view=aspnetcore-3.0

環境

  • Visual Studio 2019 16.2.0 Preview 4.0
  • .NET Core SDK 3.0.100-preview6-012264

手順

  • Visual Studio のプロジェクトテンプレートから「ASP.NET Core Web アプリケーション / Blazor サーバーアプリ」を選択し、プロジェクトを生成する。(認証なしで作成)

  • NuGet で以下のパッケージを追加する。
    <PackageReference Include="Microsoft.AspNetCore.Authentication.Google" Version="3.0.0-preview6.19307.2" />

  • Google Developer Console で OAuth のクライアントID等を取得し、appsettings.json か Secret Manager に設定する。
    リダイレクトURLの設定とかもやる。( http://localhost:8080/signin-google とかを追加。※ポート番号確認すること)
    https://docs.microsoft.com/aspnet/core/security/app-secrets

<details><div>

"Authentication": {
  "Google": {
    "ClientId": "",
    "ClientSecret": ""
  }
}

</div></details>

  • Startup クラスを以下のように変更。

<details><div>

...
public void ConfigureServices(IServiceCollection services)
{
...
+   services.AddAuthentication(option => {
+       option.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
+       option.DefaultChallengeScheme = GoogleDefaults.AuthenticationScheme;
+   })
+   .AddCookie()
+   .AddGoogle(options => {
+       var google = this.Configuration.GetSection("Authentication:Google");
+           options.ClientId = google["ClientId"];
+           options.ClientSecret = google["ClientSecret"];
+   });

+   services.AddControllers();
   
    services.AddRazorPages();
    services.AddServerSideBlazor();
...
}
...
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
    app.UseRouting();

+   app.UseAuthentication();
+   app.UseAuthorization();

    app.UseEndpoints(endpoints => {
        endpoints.MapBlazorHub();
+       endpoints.MapDefaultControllerRoute();
        endpoints.MapFallbackToPage("/_Host");
    });
...
}

</div></details>

  • 以下の Shared/LoginDisplay.razor を作成する。

<details><div>

<AuthorizeView>
    <Authorized>
        <text>Hello, @context.User.Identity.Name!</text>
        <a href="Account/Logout">Log out</a>
    </Authorized>
    <NotAuthorized>
        <a href="Account/Login">Log in</a>
    </NotAuthorized>
</AuthorizeView>

</div></details>

  • MainLayout.razor を以下のように変更

<details><div>

...
<div class="main">
    <div class="top-row px-4">
+       <LoginDisplay />
        <a href="https://docs.microsoft.com/en-us/aspnet/" target="_blank">About</a>
    </div>
...

</div><details>

  • Controllers/AccountController.cs を作成し以下の AccountController クラスを作る。

<details><div>

public class AccountController: Controller
{
    public IActionResult Login()
    {
        return this.Challenge(new AuthenticationProperties {
            RedirectUri = "/"
        });
    }

    public IActionResult Logout()
    {
        return this.SignOut(new AuthenticationProperties {
            RedirectUri = "/"
    });
}

</div></details>

  • FetchData.razor 等のページに @attribute [Authorize] を付ける。

おわり。

※ これはとりあえず動くようにしただけなので Cookie の設定とかいろいろ後でちゃんとやること。リダイレクト周りとか。オープンリダイレクト注意。
https://docs.microsoft.com/aspnet/core/security/preventing-open-redirects

Discussion