> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Regular Web Apps 向けシングルサインオン（SSO）アーキテクチャシナリオ用の ASP.NET Core 実装

# ASP.NET Core 実装（Web Apps + SSO）

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****マスク済み*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

ASP.NET Core 実装の完全なソースコードは、[この GitHub リポジトリ](https://github.com/auth0-samples/auth0-pnp-webapp-oidc)で確認できます。

<div id="configure-the-cookie-and-oidc-middleware">
  ## Cookie と OIDC ミドルウェアを設定する
</div>

このガイドでは、シンプルなホスト型ログインを使用します。ASP.NET Core で利用できる標準の Cookie および OIDC ミドルウェアを使用するため、NuGet パッケージをインストールしておいてください。

```bash lines theme={null}
Install-Package Microsoft.AspNetCore.Authentication.Cookies
Install-Package Microsoft.AspNetCore.Authentication.OpenIdConnect
```

次に、アプリケーションのミドルウェア パイプラインで、Cookie と OIDC のミドルウェアを構成します。

export const codeExample = `public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // 認証サービスを追加します
        services.AddAuthentication(
            options => options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme);

        // 簡潔にするため、一部のコードは省略しています...
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IOptions<Auth0Settings> auth0Settings)
    {
        // 簡潔にするため、一部のコードは省略しています...

        // クッキー ミドルウェアを追加します
        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            AutomaticAuthenticate = true,
            AutomaticChallenge = true
        });

        // OIDC ミドルウェアを追加します
        app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions("Auth0")
        {
            // Authority を Auth0 のドメインに設定します
            Authority = "https://{yourDomain}/",

            // Auth0 のクライアントID とクライアントシークレットを設定します
            ClientId = {yourClientId},
            ClientSecret = {yourClientSecret},

            // 認証と Challenge を自動的に実行しないようにします
            AutomaticAuthenticate = false,
            AutomaticChallenge = false,

            // response type を code に設定します
            ResponseType = "code",

            CallbackPath = new PathString("/signin-auth0"),

            // Claims Issuer を Auth0 に設定します
            ClaimsIssuer = "Auth0"
        });

        // 簡潔にするため、一部のコードは省略しています...
    }
}`;

<AuthCodeBlock children={codeExample} language="csharp" />

上記のコードからわかるように、2 種類の認証ミドルウェアを設定しています。

1 つ目は cookie ミドルウェアで、`UseCookieAuthentication` の呼び出しによって登録されています。2 つ目は OIDC ミドルウェアで、`UseOpenIdConnectAuthentication` の呼び出しによって設定されます。

ユーザーが OIDC ミドルウェアを使用して Auth0 にサインインすると、その情報は自動的に<Tooltip tip="Session Cookie: Entity that, when present, allows the user to be considered authenticated." cta="View Glossary" href="/ja/docs/glossary?term=session+cookie">セッションクッキー</Tooltip>に保存されます。必要なのは、上記のようにミドルウェアを設定することだけで、あとはユーザーセッションの管理を自動的に処理します。

また、<Tooltip tip="OpenID: Open standard for authentication that allows applications to verify users' identities without collecting and storing login information." cta="View Glossary" href="/ja/docs/glossary?term=OpenID">OpenID</Tooltip> Connect (OIDC) ミドルウェアは、ユーザーの認証後に Auth0 から送信される<Tooltip tip="OpenID: Open standard for authentication that allows applications to verify users' identities without collecting and storing login information." cta="View Glossary" href="/ja/docs/glossary?term=ID+Token">IDトークン</Tooltip>からすべてのクレームを抽出し、それらを`ClaimsIdentity` にクレームとして追加します。

<div id="implement-the-logout">
  ## ログアウトを実装する
</div>

`AuthenticationManager` クラスの `SignOutAsync` メソッドを使用し、サインアウトしたい認証スキームを渡すことで、アプリケーション セッションと Auth0 セッションの両方を制御できます。

たとえば、cookie ミドルウェアからサインアウトしてアプリケーションの認証 cookie をクリアするには、次のように呼び出します。

```csharp wrap lines theme={null}
await HttpContext.Authentication.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
```

同様に、`SignOutAsync` メソッドを呼び出し、サインアウト対象の認証スキームとして `Auth0` を渡すことで、Auth0 からユーザーをログアウトできます。

```csharp lines theme={null}
await HttpContext.Authentication.SignOutAsync("Auth0");
```

上記を機能させるには、OIDC ミドルウェアの登録時に `OnRedirectToIdentityProviderForSignOut` イベントを処理する追加の構成も必要です。イベント内では、Auth0 の cookie をクリアするため、[Auth0 のログアウトエンドポイント](https://auth0.com/docs/api/authentication/reference#logout) にリダイレクトする必要があります。

```csharp lines theme={null}
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions("Auth0")
{
    // 簡略化のため一部のコードを省略
    Events = new OpenIdConnectEvents
    {
        OnRedirectToIdentityProviderForSignOut = context =>
        {
            context.Response.Redirect($"https://{auth0Settings.Value.Domain}/v2/logout?client_id={auth0Settings.Value.ClientId}&returnTo={context.Request.Scheme}://{context.Request.Host}/");
            context.HandleResponse();

            return Task.FromResult(0);
        }
    }
});
```

また、<Tooltip tip="Auth0 Dashboard: サービスを設定するための Auth0 の主要製品です。" cta="用語集を表示" href="/ja/docs/glossary?term=Auth0+dashboard">Auth0 Dashboard</Tooltip> で、アプリケーションの **Allowed Logout URLs** にアプリケーションの URL を追加してください。詳細については、[ログアウト](/ja/docs/authenticate/login/logout) を参照してください。

<div id="implement-admin-permissions">
  ## Admin 権限の実装
</div>

グループを ASP.NET Core アプリケーションに統合する最も簡単な方法は、ASP.NET Core で利用できる組み込みの [ロールベースの認可](https://docs.asp.net/en/latest/security/authorization/roles.html) を使用することです。これを実現するには、次の型のクレームを追加する必要があります

```http lines theme={null}
http://schemas.microsoft.com/ws/2008/06/identity/claims/role
```

ユーザーに割り当てられている各グループごとに。

クレームが追加されると、`[Authorize(Roles = "Admin")]` 属性でそのクレームを修飾することで、特定のアクションを `Admin` ユーザーのみが実行できるよう簡単に制限できます。また、コントローラー内から `User.IsInRole("Admin")` を呼び出して、ユーザーが特定のロールに属しているかどうかをコードで確認することもできます。

ASP.NET OIDC ミドルウェアは、<Tooltip tip="JSON Web Token (JWT): 当事者間でクレームを安全に表現するために使用される標準的な IDトークン の形式（多くの場合は アクセストークン の形式でもあります）。" cta="用語集を見る" href="/ja/docs/glossary?term=JWT">JWT</Tooltip> で返されるすべてのクレームを、自動的に `ClaimsIdentity` のクレームとして追加します。したがって、`authorization` クレームから情報を抽出し、そのクレームの JSON 本文をデシリアライズして、各グループについて `http://schemas.microsoft.com/ws/2008/06/identity/claims/role` クレームを `ClaimsIdentity` に追加する必要があります。

```csharp lines expandable theme={null}
app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions("Auth0")
{
    // 簡潔にするため、一部の設定を省略しています

    Events = new OpenIdConnectEvents
    {
        OnTicketReceived = context =>
        {
            var options = context.Options as OpenIdConnectOptions;

            // ClaimsIdentity を取得する
            var identity = context.Principal.Identity as ClaimsIdentity;
            if (identity != null)
            {
                // グループをロールとして追加する
                var authzClaim = context.Principal.FindFirst(c => c.Type == "authorization");
                if (authzClaim != null)
                {
                    var authorization = JsonConvert.DeserializeObject<Auth0Authorization>(authzClaim.Value);
                    if (authorization != null)
                    {
                        foreach (var group in authorization.Groups)
                        {
                            identity.AddClaim(new Claim(ClaimTypes.Role, group, ClaimValueTypes.String, options.Authority));
                        }
                    }
                }
            }

            return Task.FromResult(0);
        }
    }
});
```

次に、管理者がタイムシートを承認できるようにするActionを追加します：

```csharp lines theme={null}
[Authorize(Roles = "Admin")]
public IActionResult TimesheetApproval()
{          
    return View();
}
```
