WebSurfer's Home

トップ > Blog 1   |   Login
Filter by APML

Password Recovery の実装 (MVC5)

by WebSurfer 17. March 2021 13:35

.NET Framework 版の ASP.NET MVC5 で ASP.NET Identity をユーザー認証に使用し、Password Recovery を実装する方法を備忘録として書いておきます。先の記事「Email Confirmation の実装 (MVC5)」の続きです。

ForgotPassword ページ

Microsoft のチュートリアル「ログイン、電子メール確認、パスワード リセットを使用して安全な ASP.NET MVC 5 Web アプリを作成する (C#)」の「パスワードの回復/リセット」以降のセクションの説明に従って実装します。

Password Recovery はユーザーがパスワードを忘れてしまっても再設定できる手段を提供するものです。ページのヘッダ右上に表示されている [ログイン] リンクをクリックして Account/Login ページを表示すると、その中に [パスワードを忘れた場合] というリンクがあります(注: デフォルトではコメントアウトされていますので解除してください)。それをクリックすると上の画像の Accpunt/ForgotPassword ページに遷移します。

その [電子メール] テキストボックスに登録したメールアドレスを入力して [電子メール リンク] ボタンをクリックすると、入力したメールアドレスが Account/ForgotPassword アクションメソッドに POST されます。

Account/ForgotPassword アクションメソッドでは、(1) 送信されたメールアドレスが登録済み、(2)Email Confirmation 済みであることを確認します。条件 (1), (2) が確認できない場合は Account/ForgotPasswordConfirmation ページにリダイレクトされるだけでそれ以外何も起こりません。

条件 (1), (2) の条件の両方が確認できたらメールを送信するのですが、そのためにはテンプレートで生成された POST 側の Account/ForgotPassword アクションメソッド内の code(確認用のトークン)の生成、メール本文に含める url 作成、メール送信のためのコードのコメントアウトを解除します。

修正後のコードは以下の通りです。

// POST: /Account/ForgotPassword
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ForgotPassword(
                                  ForgotPasswordViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = await UserManager.FindByNameAsync(model.Email);
        if (user == null || 
            !(await UserManager.IsEmailConfirmedAsync(user.Id)))
        {
            return View("ForgotPasswordConfirmation");
        }

        // code の生成、メール本文に含める Accout/ResetPassword
        // への url 作成(既存のコードのコメントアウトを解除)
        string code = await UserManager
                      .GeneratePasswordResetTokenAsync(user.Id);
        var callbackUrl = Url.Action("ResetPassword", 
                          "Account", 
                          new { userId = user.Id, code = code }, 
                          protocol: Request.Url.Scheme);

        // メール送信。既存のコードのコメントアウト解除でもよいが、
        // ユーザーのメーラーが html の表示を許可していない可能性を
        // 考えて、html の a 要素を組み立てて送るのではなく、url そ
        // のものを送信するように変更した
        await UserManager.SendEmailAsync(user.Id,
            "Reset Password",
            "Please confirm your account by: " +
            Server.HtmlEncode(callbackUrl).Replace("&amp;", "&"));

        return RedirectToAction("ForgotPasswordConfirmation", 
                                "Account");
    }

    return View(model);
}

メールが送信された後、Account/ForgotPasswordConfirmation ページにリダイレクトされ、以下のような画面が表示されます。ユーザーにメールを見るよう促しているだけです。

ForgotPasswordConfirmation ページ

上のコードで送信されたメールは以下の画像のようになります。メール本文には Account/ResetPassword ページへの url が含まれ、それに userId と code がクエリ文字列として設定されています。

Reset Password メール

メールの url をクリックすると Account/ResetPassword ページが GET 要求され、クエリ文字列から userId と code が渡されます。その応答としてブラウザに以下のような画面が表示されます。

ResetPassword ページ

上のページに、最初に Account/ForgotPassword ページで入力したのと同じメールアドレスと、新しいパスワードを入力して [再設定] ボタンをクリックすると、メールアドレスとトークンが有効であればパスワードが新しいものに変更され、その後 ResetPasswordConfirmation ページにリダイレクトされます。

ResetPasswordConfirmation ページ

そのページのリンク [ここをクリックしてログイン] をクリックすると Account/Login ページに遷移するので、そこでメールアドレスと新しいパスワードを入力すればログインできます。


ユーザー登録の場合と違って、Password Recovery ではメールが受信でき、それに含まれるトークンを ResetPassword ページに送信し、そのページで新しいパスワードを登録できないと何ともならない・・・すなわちメール送信機能の実装は必須のコーディングとなっています。

メール送信機能を実装しなくても Password Recovery を可能にするには、コードを書き換えて、 ForgotPasswordConfirmation ページで上に書いた条件 (1), (2) の条件の両方が確認できたら、ResetPassword ページにリダイレクトするといった修正が必要と思われます。(未検証・未確認です)

Tags: , ,

MVC

Email Confirmation の実装 (MVC5)

by WebSurfer 16. March 2021 21:22

.NET Framework 版の ASP.NET MVC5 で ASP.NET Identity をユーザー認証に使用し、Email Confirmation を実装する方法を備忘録として書いておきます。

Email Confirmation

以前は Microsoft のチュートリアル「ログイン、電子メール確認、パスワード リセットを使用して安全な ASP.NET MVC 5 Web アプリを作成する (C#)」に従って生成されたコードに手を加えれば実装できたのですが、SendGrid が id と password による認証をサポートしなくなり、Api Key による認証を使うように変更する必要が生じました。

Core 版の MVC アプリ用には Api Key による認証を使う SendGrid による Email Confirmation のチュートリアルがあります(先の記事「Email Confirmation の実装 (CORE)」とそれからリンクが貼ってある Microsoft の記事を見てください)。それを参考に実装してみました。以下にその概要を書きます。

(1) プロジェクトの作成

Visual Studio 2019 の[新規作成(N)]⇒[プロジェクト(P)...]で「新しいプロジェクト」ダイアログを表���し、その中の「ASP.NET Web アプリケーション (.NET Framework)」テンプレートを選択して ASP.NET MVC アプリを作成します。

ASP.NET MVC アプリの作成

ASP.NET Identity による認証を実装する必要がありますので、上の画像のように認証に「個別のユーザーアカウント」を使用するように設定してください。

テンプレートで自動生成された認証関係のコードに手を加えて Email Confirmation の機能を実装します。

テンプレートが生成したデフォルトのコードでは、Accout/Register アクションメソッドでユーザーが登録に成功すると直ちにログインした状態になります。アクションメソッドにはメールを送信するコードが含まれていますがコメントアウトされています。

App_Data/IdentityConfig.cs ファイルに EmailService クラスというメール送信のためのクラスが定義されていて、クライアントからの要求を受けるとインスタンス化されて ApplicationUserManager に登録されます。ただし、EmailService クラスの SendAsync メソッドの中身が実装されてないのでメールを送ることはできません。

メールを送信するためには SendAsync メソッドに SendGrid を利用したメール送信機能を実装します。そして、Accout/Register に含まれているメール送信のためのコードのコメントアウトを解除します。

そうすることにより、ユーザー登録完了時点で登録したメールアドレスにメールが送信されます。ユーザーが受け取ったメール本文に含まれる url をクリックすると Accout/ConfirmEmail にクエリ文字列で設定された情報が送信され、サーバー側ではそれを確認してデータベースの AspNetUsers テーブルの EmailConfirmed フィールドを ture に設定します。

Account/Login アクションメソッドには、EmailConfirmed フィールドが ture になっている場合のみログインを許可するコードを追加します。これによりユーザーが送られてきたメール本文に含まれる url をクリックしない限りログインできないということになります。

(2) API Key の入手

メールの送信には SendGrid を利用します。ユーザー登録して API Key を入手してください。(先の記事「Email Confirmation の実装 (CORE)」のステップ (3) を見てください)

SendGrid は基本的に有償ですが、開発目的で送信するようなメールの数が少ない(一日 100 件以内だそうです)の場合は Free のサービスでよさそうです。

(3) SendGrid のインストール

NuGet を利用してプロジェクトに SendGrid をインストールします。

SendGrid をインストール

この記事では自分がインストールした時点での最新版 v9.22.0 を使いました。Microsoft のチュートリアル「ログイン、電子メール確認、パスワード リセットを使用して安全な ASP.NET MVC 5 Web アプリを作成する (C#)」にある SendGrid.Net40 とは違うので注意してください(それも一緒にインストールされますが)。

(4) API Key の保存

メールの差出人と SendGrid の API Key は web.config に保存します。暗号化などを考えた方が良いのかもしれませんが、この記事では簡略化のため生の Api Key を保存しています。

<appSettings>
  <add key="SendGridUser" value="WebSurfer" />
  <add key="SenGridKey" value="SG...t-A" />
</appSettings>

(5) EmailSender クラスの実装

メールを送信するため App_Data/IdentityConfig.cs の EmailService クラスにメール送信機能を実装します。

Microsoft のチュートリアル「Account confirmation and password recovery in ASP.NET Core」にあるコードを参考に以下のようにしました。

using System;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using Mvc5EmailConfirmation.Models;

using SendGrid;
using SendGrid.Helpers.Mail;
using System.Configuration;

namespace Mvc5EmailConfirmation
{
    public class EmailService : IIdentityMessageService
    {
        public Task SendAsync(IdentityMessage message)
        {
            return Execute(ConfigurationManager.AppSettings["SenGridKey"], 
                       message.Subject, message.Body, message.Destination);
        }

        public Task Execute(string apiKey, string subject, 
                            string message, string email)
        {
            var client = new SendGridClient(apiKey);
            var msg = new SendGridMessage()
            {
                From = new EmailAddress("差出人メールアドレス",
                       ConfigurationManager.AppSettings["SendGridUser"]),
                Subject = subject,
                PlainTextContent = message,
                HtmlContent = message
            };
            msg.AddTo(new EmailAddress(email));

            msg.SetClickTracking(false, false);

            return client.SendEmailAsync(msg);
        }
    }

    // ・・・中略・・・
}

Core 版 MVC のチュートリアルの場合は Register メソッドから宛先メールアドレス、Subject、本文が直接渡されるのですが、.NET Framework 版 MVC5 のテンプレートで生成される SendAsync メソッドには UserManager 経由で IdentityMessage オブジェクトが渡されます。

その中に宛先メールアドレス、Subject、本文が含まれていますので、それぞれ Destination, Subject, Body プロパティを使って取得しています。

(6) Account/Register ページの修正

テンプレートで生成された SignInManager.SignInAsync メソッドをコメントアウトし、code の生成、メール本文に含める Accout/ConfirmEmail への url 作成、メール送信のためのコードのコメントアウトを解除します。

さらに、Home/Index にリダイレクトする既存のコードをコメントアウトし、代わりに登録完了後メール確認を促すページ Info を表示するようコードを追加します。Views/Shared/Info.cshtml をチュートリアルに従い作成・追加してください。

修正後のコードは以下の通りです。(修正は POST 側のみで GET 側は不要です)

// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new ApplicationUser 
        { 
            UserName = model.Email, 
            Email = model.Email 
        };

        var result = await UserManager.CreateAsync(user, 
                                                   model.Password);

        if (result.Succeeded)
        {
            // 登録時にはログインさせないようコメントアウト
            //await SignInManager.SignInAsync(user, 
            //                                isPersistent:false, 
            //                                rememberBrowser:false);

            // code の生成、メール本文に含める Accout/ConfirmEmail
            // への url 作成(既存のコードのコメントアウトを解除)
            string code = await UserManager
                          .GenerateEmailConfirmationTokenAsync(user.Id);
            var callbackUrl = Url.Action("ConfirmEmail", 
                              "Account", 
                              new { userId = user.Id, code = code }, 
                              protocol: Request.Url.Scheme);

            // メール送信。既存のコードのコメントアウト解除でもよいが、
            // ユーザーのメーラーが html の表示を許可していない可能性を
            // 考えて、html の a 要素を組み立てて送るのではなく、url そ
            // のものを送信するように変更した
            await UserManager.SendEmailAsync(user.Id, "Confirm your email",
                "Please confirm your account by: " +
                Server.HtmlEncode(callbackUrl).Replace("&amp;", "&"));

            // メール確認を促すページ Info に表示するメッセージ
            ViewBag.Message = "Check your email and confirm your account," +
                " you must be confirmed before you can log in.";

            // チュートリアルに従い Views/Shared/Info.cshtml を別途作成要
            return View("Info");

            // これはコメントアウト
            //return RedirectToAction("Index", "Home");
        }
        AddErrors(result);
    }
    return View(model);
}

以上により、ユーザーが登録に成功するとこの記事の一番上の画像のとおり Info ページが表示され、ユーザーにメール確認を促します。

さらに、ユーザーが登録したメールアドレスに以下のメールが送信されます。メール本文にある url が Accout/ConfirmEmail となっており、クエリ文字列に userId と code が設定されています。ユーザーがこれをクリックすることにより Accout/ConfirmEmail に userId と code が送信され、メール確認が完了します(AspNetUsers テーブルの EmailConfirmed フィールドが ture に設定されます)。

確認メール

(7) Account/Login ページの修正

EmailConfirmed フィールドが ture になっているか否かを確認し true の場合のみログインを許可するコードを追加します。これによりユーザーが送られてきたメール本文に含まれる url をクリックしない限りログインできないということになります。

さらに、メール確認なしでログインしようとするとエラーメッセージを表示するためのコードも追加します。メッセージは Error ページ表示しますので、チュートリアルに従い Views/Shared/Error.cshtml を書き換えてください。

修正後のコードは以下の通りです。(修正は POST 側のみで GET 側は不要です)

// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, 
                                      string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    // メール確認がされてない場合はログインできないようにする
    var user = await UserManager.FindByNameAsync(model.Email);
    if (user != null)
    {
        if (!await UserManager.IsEmailConfirmedAsync(user.Id))
        {
            ViewBag.errorMessage = 
                "You must have a confirmed email to log on.";

            // チュートリアルに従い Views/Shared/Error.cshtml 
            // を書き換えないと上のエラーメッセージは表示され
            // ないので注意
            return View("Error");
        }
    }

    var result = await SignInManager
                 .PasswordSignInAsync(model.Email, 
                                      model.Password, 
                                      model.RememberMe, 
                                      shouldLockout: false);
    switch (result)
    {
        case SignInStatus.Success:
            return RedirectToLocal(returnUrl);
        case SignInStatus.LockedOut:
            return View("Lockout");
        case SignInStatus.RequiresVerification:
            return RedirectToAction("SendCode", 
                new { ReturnUrl = returnUrl, 
                      RememberMe = model.RememberMe });
        case SignInStatus.Failure:
        default:
            ModelState.AddModelError("", "無効なログイン試行です。");
            return View(model);
    }
}

次はユーザーがパスワードを忘れてしまった場合の Password Recovery の実装ですが、この記事で続けると長くなりすぎるので別の記事「Password Recovery の実装 (MVC5)」に書きます。

Tags: , ,

MVC

プロファイル情報の追加 (.NET 版)

by WebSurfer 26. May 2020 16:23

.NET Framework 版の ASP.NET MVC5 アプリに ASP.NET Identity を利用したユーザー認証を実装して、プロファイル情報としてハンドル名を追加し、ログイン時にページのヘッダ右上にハンドル名(デフォルトはメールアドレス)を表示する方法を書きます。

ハンドル名を表示

先の記事「プロファイル情報の追加 (CORE 版)」の .NET Framework 版です。CORE 版とは基本的なところでの大きな差はありませんが、細かいところでいろいろ違うので備忘録として残しておくことにしました。

(1) プロジェクトの作成

以下の説明は、Visual Studio 2019 を使って Mvc5ProfileInfo という名前で作成した ASP.NET MVC5 アプリのプロジェクトをベースしています。

プロジェクトの作成

デフォルトでは認証は「認証なし」になっていますが、それを「個別のユーザーアカウント」に変更します。それによって ASP.NET Identity を利用したユーザー認証のためのソースコードが一式自動生成されます。

(2) HandleName プロパティの追加

Models/IdentityModels.cs ファイルに IdentityUser を継承した ApplicationUser クラスが定義されています。それに HandleName プロパティを追加します。以下の画像の赤枠部分がそれです。

HandleName プロパティの追加

そのあと Migration 操作を行うと Entity Framework Code First の機能によりデータベースには HandleName フィールドが作られます。HandleName フィールドはデータアノテーション属性の Required により NULL 不可に、StringLength の引数 256 により nvarchar(256) になります。

(3) Enable-Migrations / Add-Migration

Visual Studio のパッケージマネージャーコンソールで Enable-Migrations コマンドを実行します。成功するとプロジェクトのルート直下に Migrations フォルダが生成され、その中に Configuration.cs という名前のクラスファイルが生成されます。

次に、Add-Migration Initial コマンドを実行します(Initial という名前は任意です)。成功すると Migrations フォルダに xxxxx_Initial.cs という名前のクラスファイルが生成されます。(xxxxx は作成日時)

Initial.cs

その中に、dbo.AspNetUsers テーブルを SQL Server に生成するコードがあります。上の画像の赤枠のコードを見てください。ステップ (2) で HandleName プロパティに付与した属性に従って HandleName というフィールドを NULL 不可、nvarchar(256) で生成するようになっています。

(注: この記事ではプロジェクト作成直後のデータベースには何もない状態から Migration 関係の操作を行っています。データーベースがすでに生成済みで、それに HandleName を追加する場合とは手順が違うので注意してください)

(4) Update-Database

Visual Studio のパッケージマネージャーコンソールで Update-Database コマンドを実行します。成功すると ASP.NET Identity 用のデータベースが Entity Framework Code First の機能によって追加されます。

ASP.NET Identity 用のデータベース

この記事では Visual Studio でプロジェクトを作成したときに自動生成された web.config をそのまま使っています。その中に "DefaultConnection" という名前で LocalDB に接続する接続文字列が定義されており、aspnet-Mvc5ProfileInfo-20200526103410.mdf という名前(数字はプロジェクトの作成日時)の .mdf ファイルを動的に LocalDB にアタッチして使うように設定されています。

Models/IdentityModels.cs ファイルには IdentityDbContext<ApplicationUser> を継承したコンテキストクラス ApplicationDbContext が定義されており、web.config の接続文字列 "DefaultConnection" を使うように設定されています。

Update-Database コマンドによって、web.config の接続文字列で LocalDB に接続し、指定された名前のデータベースを LocalDB に作成し、ステップ (3) で生成されたクラスファイル xxxxx_Initial.cs に従って ASP.NET Identity 用のテーブルを生成します。

その結果が上の画像です。aspnet-Mvc5ProfileInfo-20200526103410 という名前のデータベースが作成され、その中の dbo.AspNetUsers テーブルにステップ (2) で HandleName プロパティを追加したとおり、HandleName フィールドが NULL 不可 nvarchar(256) で生成されています。

(5) Register アクションメソッドの修正

Controllers/AccountController.cs の Register アクションメソッドに以下の画像の赤枠のコードを追加します。登録時にハンドル名を自動的に Email と同じになるようにするものです。

Register アクションメソッドの修正

ステップ (4) の画像の通り dbo.AspNetUsers テーブルの HandleName フィールドは NULL 不可になっています。そのため、新規ユーザーの登録を行う際 HandleName を入力しないと CreateAsync でエラーとなります。なので、初回登録時はとりあえずハンドル名は Email と同じになるようにしました。

登録時にユーザーにハンドル名を決めて入力してもらうようにもできますが、そういう手間を増やすと嫌がられそうですし、ユーザーによってはハンドル名は Email と同じでよいという人もいるでしょうから。

ここまで実装できれば、アプリケーションを実行してユーザー登録が可能になり、登録操作を行うと dbo.AspNetUsers テーブルの HandleName フィールドにはメールアドレスと同じ文字列が設定されているはずです。

(6) ハンドル名の変更機能を実装

ログイン後、ページのヘッダの右上のユーザー名(デフォルトで Email)をクリックすると Manage/Index ページに遷移しますが、そこからさらにリンクをたどって別ページに飛んで、そこでユーザーがハンドル名を任意に変更できるようにします。

ハンドル名の変更は、Manage コントローラーに ChangeHandleName という名前のアクションメソッドを追加しそこで行うようにします。

まず、Manage/Index ページのビュー Views/Manage/Index.cshtml に ChangeHandleName アクションメソッドへのリンクを追加します。

ChangeHandleName へのリンク追加

変更が完了した際に Manage/Index ページに表示するためのメッセージを追加します。Controllers/ManageController.cs ファイルを開いて以下の画像の赤枠のコードを追加します(2 箇所)。

メッセージを追加

メッセージを追加

Models/ManageViewModels.cs に ChangeHandleName アクションメソッドとビューの間でデータをやり取りするための ChangeHandleNameViewModel クラスを追加します。入力できるハンドル名の長さはとりあえず 30 文字に制限してみました。

// HandleName 変更用に追加
public class ChangeHandleNameViewModel
{
    [Required]
    [Display(Name = "旧ハンドル名")]
    public string OldHandleName { get; set; }

    [Required(ErrorMessage = "{0}は必須")]
    [StringLength(30, ErrorMessage = "{0} は {1} 文字以内")]
    [Display(Name = "新ハンドル名")]
    public string NewHandleName { get; set; }
}

Views/Manage/Index.cshtml に ChangeHandleName アクションメソッドのコードを追加します。旧ハンドル名を入力できるようになっていたり、いきなり例外をスローするところがちょっと乱暴かもしれませんが、検証用ということで・・・

// GET: /Manage/ChangeHandleName
public async Task<ActionResult> ChangeHandleName()
{
    var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
    if (user == null)
    {
        throw new InvalidOperationException(
            "ログイン中のユーザー情報が削除されました。");
    }

    var model = new ChangeHandleNameViewModel();
    model.OldHandleName = user.HandleName;
    return View(model);
}

// POST: /Manage/ChangeHandleName
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ChangeHandleName(ChangeHandleNameViewModel model)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
    if (user == null)
    {
        throw new InvalidOperationException(
            "ログイン中のユーザー情報が削除されました。");
    }

    if (model.OldHandleName != user.HandleName)
    {
        throw new InvalidOperationException(
            "DB に既存のハンドル名と旧ハンドル名が一致しません。");
    }

    user.HandleName = model.NewHandleName;
    var result = await UserManager.UpdateAsync(user);
    if (result.Succeeded)
    {
        return RedirectToAction("Index", 
            new { Message = ManageMessageId.ChangeHandleNameSuccess });
    }
    AddErrors(result);
    return View(model);
}

アクションメソッドを追加したら、スキャフォールディングのデザイナで[テンプレート(T)]を Edit とし[モデルクラス(M)]を上に定義した ChangeHandleNameViewModel としてビューを追加します。コードは自動生成されたものがほぼそのまま使えますのでこの記事に書くのは割愛します。

(7) ハンドル名の変更操作

ユーザーがログインするとページのヘッダの右上に Hello xxxxx! と表示され、それが Manage/Index ページへのリンクになります。それをクリックして Manage/Index ページを表示し、その中のリンク[ハンドル名の変更]をクリックするとすると Manage/ChangeHandleName ページに遷移します。

ChangeHandleName ページ

上の[新ハンドル名]テキストボックスに新しいハンドル名を入力し[Save]ボタンをクリックするとデータベースの HandleName フィールドが更新され、その後 Manage/Index ページにリダイレクトされます。

Manage/Index ページにリダイレクト

赤枠で示した部分にステップ (6) で追加したメッセージが表示されているところに注目してください。

(8) ClaimsIdentity へ追加

ページのヘッダの右上に Hello xxxxx! と表示される xxxxx にはデフォルトではメールアドレスが表示されますが(ステップ (7) の画像参照)、それをハンドル名に変更します。結果、この記事の一番上の画像のようになります。

プロファイル情報を Claim として ClaimsIdentity オブジェクトに追加し、拡張メソッドを使って ClaimsIdentity オブジェクトからハンドル名を取得・表示するようにしています。

プロジェクト作成時に自動生成された Models/IdentityModels.cs ファイルの ApplicationUser クラスにそのコードを書く場所がコメントで「ここにカスタム ユーザー クレームを追加します」と示されているので、そこに追加します。以下の画像の上の赤枠部分の通りです。

カスタムユーザークレーム

ClaimsIdentity オブジェクトからハンドル名を取得する拡張メソッドもそこに書いておきます。画像の下の赤枠のコードがそれです。

画像には表示されていませんが、using 句で名前空間 System.Linq と System.Security.Principal を取り込むようにしてください。

拡張メソッドは名前空間をインポートすればスコープの中に取り込むことができます。この記事の一番上の画像のようにレイアウトページの右上に表示する場合は Views/Shared/_LoginPartial.schtml に名前空間 Mvc5ProfileInfo.Models を取り込んで User.Identity.GetHandleName() というコードで取得します。

ClaimsIdentity オブジェクトにハンドル名を追加すると、認証クッキーにハンドル名が含まれるようになります。認証クッキーからハンドル名を取得できれば、毎回データベースにクエリを投げて取得するより負荷は軽い(であろう)というのが ClaimsIdentity を使う理由です。

Tags: , , ,

MVC

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  April 2021  >>
MoTuWeThFrSaSu
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

View posts in large calendar