メインコンテンツへスキップ
Auth0 を使用すると、ASP.NET OWIN アプリケーションに数分で認証を追加できます。このガイドでは、クラシック ASP.NET OWIN アプリケーションにログイン、ログアウト、ユーザープロフィールの表示を追加する方法を説明します。 このガイドを完了すると、アプリケーションで次のことができるようになります。
  • ユーザーがサインインすると Auth0 Universal Login にリダイレクトする
  • コールバックを処理し、セッションを Cookie に保存する
  • 認証済みユーザーの名前、メールアドレス、ユーザープロファイル画像を表示する
  • アプリと Auth0 の両方からユーザーをサインアウトする
このガイドは、OWIN を使用する クラシック ASP.NET (.NET Framework) アプリケーションを対象としています。アプリケーションがすでに ASP.NET Core で実行されている場合は、代わりに Auth0.AspNetCore.Authentication SDK を使用してください。

前提条件

開始する前に、次のものを用意してください。
  • Auth0 アカウント - 無料でサインアップ
  • OWIN が有効な、.NET Framework を対象とする既存の ASP.NET MVC アプリケーション、または Visual Studio の ASP.NET Web Application (.NET Framework) → MVC テンプレートから作成した新規アプリケーション
  • Visual Studio 2019 以降 (または .NET Framework MVC プロジェクトをサポートする任意の IDE)

手順

1

Auth0 アプリケーションを設定する

Auth0を使用するすべてのアプリケーションは、Auth0 Dashboardに登録する必要があります。Auth0が発行するクライアントIDドメインを使用して、アプリはAuth0と通信します。Auth0アプリケーションの作成と設定は、Auth0 CLIを使って自動的に行うか、Dashboardから手動で行うことができます。
プロジェクトのルートディレクトリで次のコマンドを実行します。これにより Auth0 アプリケーションが作成され、認証情報が設定済みの、すぐに貼り付け可能な Web.config スニペットが出力されます。
brew tap auth0/auth0-cli && brew install auth0 && auth0 login --no-input && \
AUTH0_RESULT=$(auth0 apps create \
  --name "My OWIN App" \
  --type regular \
  --auth-method post \
  --callbacks http://localhost:3000/callback \
  --logout-urls http://localhost:3000/ \
  --web-origins http://localhost:3000 \
  --reveal-secrets \
  --json \
  --metadata created_by="quickstart-docs-cli") && \
CLIENT_ID=$(echo $AUTH0_RESULT | jq -r '.client_id') && \
DOMAIN=$(echo $AUTH0_RESULT | jq -r '.domain') && \
echo "Add the following to your Web.config <appSettings> section:" && \
echo "<add key=\"auth0:Domain\" value=\"$DOMAIN\" />" && \
echo "<add key=\"auth0:ClientId\" value=\"$CLIENT_ID\" />"
出力された 2 行の <add> を、Web.config<appSettings> セクションにコピーします。
Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <!-- ここに出力を貼り付けます -->
  </appSettings>
</configuration>
アプリを別のポートで実行している場合は、上記の各 URL の 3000 を実際のポート番号に置き換えてください。
2

NuGet パッケージをインストールする

必要な 2 つの OWIN ミドルウェア パッケージをプロジェクトに追加します。
パッケージ用途
Microsoft.Owin.Security.OpenIdConnectAuth0 での OpenID Connect (OIDC) 認証フローを処理します
Microsoft.Owin.Security.Cookiesログイン後、ブラウザーの Cookie にユーザー セッションを保持します
Visual Studio で Package Manager Console (Tools → NuGet Package Manager → Package Manager Console) を開き、次を実行します。
Install-Package Microsoft.Owin.Security.OpenIdConnect
Install-Package Microsoft.Owin.Security.Cookies
OWIN の Cookie ミドルウェアを System.Web の Cookie と併用すると、問題が発生することがあります。Cookie が二重に設定される問題が発生した場合は、System.Web cookie integration issues のガイダンスを参照してください。
3

OWIN ミドルウェアを設定する

OWIN ミドルウェアは、スタートアップ クラスで登録します。プロジェクトにすでに OWIN スタートアップ クラス (通常は App_Start/Startup.Auth.cs) がある場合は、その ConfigureAuth メソッドを更新してください。ない場合は、ここでファイルを作成します。Cookie ミドルウェアOpenID Connect ミドルウェア の両方が必要であり、必ず次の順序で登録する必要があります。
  1. Cookie ミドルウェア - 認証済みユーザー セッションを保存します
  2. OpenID Connect ミドルウェア - Auth0 のログイン フローとログアウト フローを処理します
App_Start/Startup.Auth.cs
using System;
using System.Configuration;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.OpenIdConnect;
using Owin;

public partial class Startup
{
    public void ConfigureAuth(IAppBuilder app)
    {
        var domain = ConfigurationManager.AppSettings["auth0:Domain"];
        var clientId = ConfigurationManager.AppSettings["auth0:ClientId"];

        // Cookieミドルウェアを最初に登録する必要があります
        app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AuthenticationType = CookieAuthenticationDefaults.AuthenticationType
        });

        app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
        {
            AuthenticationType = "Auth0",
            Authority = $"https://{domain}",
            ClientId = clientId,
            ResponseType = OpenIdConnectResponseType.CodeIdToken,
            Scope = "openid profile email",
            TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
            {
                NameClaimType = "name"
            },
            Notifications = new OpenIdConnectAuthenticationNotifications
            {
                RedirectToIdentityProvider = notification =>
                {
                    if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.Logout)
                    {
                        // Auth0のログアウトURLを構築してリダイレクトする
                        var logoutUri = $"https://{domain}/v2/logout?client_id={clientId}";
                        notification.Response.Redirect(logoutUri);
                        notification.HandleResponse();
                    }

                    return Task.FromResult(0);
                }
            }
        });
    }
}
ConfigureAuthStartup.csConfiguration メソッド内で呼び出されるようにしてください。
Startup.cs
using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(Startup))]

public partial class Startup
{
    public void Configuration(IAppBuilder app)
    {
        ConfigureAuth(app);
    }
}
AuthenticationType"Auth0" に設定されています。この文字列は、次の手順でログインの Challenge をトリガーする際に使用します。RedirectToIdentityProvider 通知はログアウト リクエストを横取りし、適切な Auth0 のログアウト URL を構築します。
4

ログイン、ログアウト、ユーザープロファイル用のアクションを追加

LoginLogoutUserProfile の 3 つのアクションを含む Controllers/AccountController.cs を作成します。
Controllers/AccountController.cs
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Auth0.AspNetCore.Authentication;

public class AccountController : Controller
{
  public ActionResult Login(string returnUrl = "/")
  {
    HttpContext.GetOwinContext().Authentication.Challenge(
      new AuthenticationProperties
      {
          RedirectUri = returnUrl ?? Url.Action("Index", "Home")
      },
      "Auth0"
    );
  }

  [Authorize]
  public ActionResult UserProfile()
  {
      var claimsIdentity = User.Identity as ClaimsIdentity;
      return View(new UserProfileViewModel()
      {
          Name = claimsIdentity?
            .FindFirst(c => c.Type == claimsIdentity.NameClaimType)?.Value,
          EmailAddress = claimsIdentity?
            .FindFirst(c => c.Type == ClaimTypes.Email)?.Value,
          ProfileImage = claimsIdentity?
            .FindFirst(c => c.Type == "picture")?.Value
      });
  }

  [Authorize]
  public void Logout()
  {
    HttpContext.GetOwinContext().Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
    HttpContext.GetOwinContext().Authentication.SignOut("Auth0");
  }
}
各アクションの動作:
  • Login - "Auth0" スキームで Challenge を呼び出します。OIDC ミドルウェアがこれを受け取り、ユーザーを Auth0 Universal Login にリダイレクトします。サインインに成功すると、ユーザーは returnUrl にリダイレクトされます。
  • UserProfile - ClaimsIdentity から認証済みユーザーのクレームを読み取り、UserProfileViewModel を通じてビューに渡します。[Authorize] 属性により、未認証のユーザーはまずログイン画面にリダイレクトされます。
  • Logout - SignOut を 2 回呼び出します。1 回はローカルの Cookie セッションをクリアするため、もう 1 回はユーザーを Auth0 からサインアウトさせるためです (これにより、アクティブな SSO セッションも終了します) 。
ユーザープロファイルデータを保持するために、Models/UserProfileViewModel.cs を作成します:
Models/UserProfileViewModel.cs
public class UserProfileViewModel
{
    public string Name { get; set; }
    public string EmailAddress { get; set; }
    public string ProfileImage { get; set; }
}
チェックポイント
アプリケーションを実行し、/Account/Login にアクセスします。Auth0 の Universal Login ページにリダイレクトされるはずです。サインイン後は、アプリケーションのホームページにリダイレクトされるはずです。Redirect URI エラーが表示される場合は、Auth0 のアプリケーション設定にあるコールバック URL が、アプリケーションの実行 URL と完全に一致していることを確認してください。
5

ユーザープロファイル画面を追加する

サインイン中のユーザー情報を表示するために、Views/Account/UserProfile.cshtml を作成します。
Views/Account/UserProfile.cshtml
@model UserProfileViewModel
@{
    ViewBag.Title = "User Profile";
}

<h2>User Profile</h2>

<div>
    <img src='@Model.ProfileImage'
         alt="Profile picture"
         style="max-width:120px; border-radius:60px;" />
</div>

<ul>
    <li><strong>Name:</strong> @Model.Name</li>
    <li><strong>Email:</strong> @Model.EmailAddress</li>
</ul>
このビューは、Auth0 が IDトークンを返す際に OIDC ミドルウェアが抽出したクレームを基に設定された UserProfileViewModel を受け取ります。
チェックポイント
ログイン後、/Account/UserProfile に移動してください。名前、メールアドレス、プロフィール画像が表示されるはずです。名前またはメールアドレスが空の場合は、OpenIdConnectAuthenticationOptionsScope"openid profile email" が含まれていることを確認してください。
6

レイアウトにログインとログアウトのリンクを追加する

ユーザーの認証状態に応じてログインリンクとログアウトリンクが表示されるよう、Views/Shared/_Layout.cshtml を更新します。
Views/Shared/_Layout.cshtml
@if (User.Identity.IsAuthenticated)
{
    <a href="@Url.Action("UserProfile", "Account")">@User.Identity.Name</a>
    <a href="@Url.Action("Logout", "Account")">Log out</a>
}
else
{
    <a href="@Url.Action("Login", "Account")">Log in</a>
}
レイアウト内でナビゲーションリンクを表示する<nav>要素内の適切な場所に、これを追加します。
チェックポイント
アプリケーションを実行します。ナビゲーションにLog inリンクが表示されるはずです。サインイン後は、そのリンクが自分の名前 (ユーザープロファイルへのリンク) に変わり、Log outリンクも表示されます。Log outをクリックすると、サインアウトしてホームページに戻るはずです。
これで、ASP.NET OWIN アプリケーションで動作する Auth0 統合の設定が完了しました。ユーザーは Auth0 Universal Login でログインし、ユーザープロファイルを表示して、ログアウトできます。

よくある問題

問題: ユーザーのサインイン後に、Auth0 で “redirect_uri mismatch” または “callback URL mismatch” エラーが表示されます。解決策: アプリから Auth0 に送信するリダイレクト URI は、Auth0 アプリケーション設定の Allowed Callback URLs のいずれか 1 つと完全に一致している必要があります。プロトコル (httphttps) 、ポート番号、パス、末尾のスラッシュに違いがないか確認してください。
問題: サインインに成功した後、認証済みページが表示されず、アプリがすぐに Auth0 にリダイレクトされます。解決策: ミドルウェアが正しい順序で登録され、OWIN パイプラインが初期化されていることを確認してください。
  • Cookie ミドルウェアは、ConfigureAuth で OpenID Connect ミドルウェアより前に登録する必要があります。
  • app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType) は、ConfigureAuth 内の最初の呼び出しである必要があります。
  • OWIN パイプラインが正しく初期化されるように、[assembly: OwinStartup(typeof(Startup))] 属性が必要です。
App_Start/Startup.Auth.cs
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType); // 最初である必要があります

app.UseCookieAuthentication(...);          // OIDC より前に Cookie ミドルウェア
app.UseOpenIdConnectAuthentication(...);   // Cookie の後に OIDC ミドルウェア
問題: ログアウトをクリックするとユーザーは Auth0 からサインアウトされますが、アプリケーションには戻りません。解決策: RedirectToIdentityProvider 通知内で、Auth0 のログアウト URL に returnTo クエリパラメーターを追加してください。戻り先 URL も、Auth0 アプリケーション設定の Allowed Logout URLs に登録されている必要があります。
App_Start/Startup.Auth.cs
var logoutUri = $"https://{domain}/v2/logout?client_id={clientId}&returnTo={Uri.EscapeDataString("http://localhost:3000/")}";
問題: ログイン後、Model.ProfileImage または Model.EmailAddress が null になります。解決策: OpenIdConnectAuthenticationOptionsScope"openid profile email" が含まれていることを確認してください。profile スコープでは名前と画像が、email スコープではメールアドレスが提供されます。
App_Start/Startup.Auth.cs
app.UseOpenIdConnectAuthentication(new OpenIdConnectAuthenticationOptions
{
    Scope = "openid profile email",  // 3 つのスコープすべてが必要です
    ...
});
問題: アプリケーションの起動時に null 参照例外または構成例外がスローされます。解決策: Web.config<appSettings>auth0:Domainauth0:ClientId の両方が存在すること、および適切な Web.config 変換が読み込まれる正しいビルド構成 (Debug/Release) で実行していることを確認してください。
Web.config
<configuration>
  <appSettings>
    <add key="auth0:Domain" value="{yourDomain}" />     <!-- 空にしてはいけません -->
    <add key="auth0:ClientId" value="{yourClientId}" /> <!-- 空にしてはいけません -->
  </appSettings>
</configuration>

高度な使い方

Startup.Auth.csRedirectToIdentityProvider 通知を変更すると、Auth0 のログインページにカスタムパラメーターを渡せます。
App_Start/Startup.Auth.cs
RedirectToIdentityProvider = notification =>
{
    if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
    {
        // ログインではなくサインアップ画面を表示する
        notification.ProtocolMessage.SetParameter("screen_hint", "signup");

        // 特定の UI ロケールを設定する
        notification.ProtocolMessage.SetParameter("ui_locales", "es");
    }

    return Task.FromResult(0);
}
アクセストークンを使用して API を呼び出すには、OIDC リダイレクト時に audience と必要な API スコープを要求します。
App_Start/Startup.Auth.cs
RedirectToIdentityProvider = notification =>
{
    if (notification.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
    {
        notification.ProtocolMessage.SetParameter("audience", "https://your-api.example.com");
        notification.ProtocolMessage.Scope += " read:data";
    }

    return Task.FromResult(0);
}
次に、認証済みユーザーのクレームからアクセストークンを取得します。
Controllers/ApiController.cs
[Authorize]
public async Task<ActionResult> CallApi()
{
    var claimsIdentity = User.Identity as ClaimsIdentity;
    var accessToken = claimsIdentity?.FindFirst("access_token")?.Value;

    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization =
        new AuthenticationHeaderValue("Bearer", accessToken);

    var response = await client.GetAsync("https://your-api.example.com/data");
    // レスポンスを処理する...
}

追加リソース

サンプルアプリケーション

このクイックスタートの完全な動作サンプル

Katana / OWIN ドキュメント

Microsoft 公式の OWIN/Katana リファレンス

コミュニティフォーラム

Auth0 コミュニティでサポートを受ける