web-dev-qa-db-ja.com

メールの検証と登録のセキュリティのためのトークンの生成

上司からcsv形式の8Kユーザーのリストが提供され、それらのユーザーのアカウントを作成するように求められました。リストには、Gmail、hotmail、組織のメールアドレスを持つユーザーがいます。

MVC 5とASP.NET ID 2を使用しています。

CSVファイルを読み取っているときに、ユーザーを作成し、以下のようにそれらのトークンを生成しています。

var userManager = new ApplicationUserManager(new UserStore<ApplicationUser>(_db));

var dataProtectionProvider = new DpapiDataProtectionProvider("Sample");
userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity")); 

string code = userManager.GenerateEmailConfirmationToken(appUser.Id);
var callbackUrl = "http://localhost:2595/Account/Verify?t="+appUser.Id+"&c="+HttpUtility.UrlEncode(code);
SendMail(callbackUrl, appUser.Email);

コールバックURLを作成したら、ユーザーにメールを送信します。ユーザーが送信したリンクをクリックすると、ユーザーはパスワード登録ページに移動し、パスワードを作成してから、作成したパスワードでログインします。

このアプローチにはセキュリティ上の欠陥がありますか?

public async Task<ActionResult> Verify(string t, string c)
        {
            if (User.Identity.IsAuthenticated)
            {
                AuthenticationManager.SignOut();
                return RedirectToAction("Index","Home");
            }

            if (t == null || c == null)
            {
                return View("Error");
            }

            var user = UserManager.FindById(t);

            if (user == null)
            {
                return View("Error");
            }

            if (user.EmailConfirmed)
            {
                return View("AlreadyConfirmed");
            }

            var result = await UserManager.ConfirmEmailAsync(t, c);
            if (result.Succeeded)
            {
                user.EmailConfirmed = true;
                UserManager.Update(user);

                ViewBag.Id = t;
                return View("ConfirmEmail");
            }

            AddErrors(result);

            return View();
        } 
3
DarthVader

あなたがコメントした詳細を考慮すると十分に安全に見えますが、ユーザーIDをコールバックから切り離し、ユーザーがまだログインしていない場合は通常どおりログインして認証を続行するのが最善の策だと思います。露出はそのままではそれほど悪くないので、ログイン後に認証ページにリダイレクトするのが面倒であれば、私はそれで問題ないと思います。

2
AJAr