IUserTokenProviderが登録されていません


101

最近Asp.Net Identity Core、申し込みフォームを1.0から2.0に更新しました。

などGenerateEmailConfirmationToken、試したかった新機能があります。

このプロジェクトを参照として使用ています。

ユーザーが登録しようとすると、RegisterのPostメソッドの実行中にエラーが発生します

private readonly UserManager<ApplicationUser> _userManager;     

public ActionResult Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var ifUserEXists = _userManager.FindByName(model.EmailId);
        if (ifUserEXists == null) return View(model);
        var confirmationToken = _userRepository.CreateConfirmationToken();//this is how i'm generating token currently.                
        var result = _userRepository.CreateUser(model,confirmationToken);
        var user = _userManager.FindByName(model.EmailId);
        if (result)
        {
            var code = _userManager.GenerateEmailConfirmationToken(user.Id);//error here
            _userRepository.SendEmailConfirmation(model.EmailId, model.FirstName, confirmationToken);
            //Information("An email is sent to your email address. Please follow the link to activate your account.");
            return View("~/Views/Account/Thank_You_For_Registering.cshtml");
        }     
    }
    
    //Error("Sorry! email address already exists. Please try again with different email id.");
    ModelState.AddModelError(string.Empty, Resource.AccountController_Register_Sorry__User_already_exists__please_try_again_);
    return View(model);
}

ラインで

 var code = _userManager.GenerateEmailConfirmationToken(user.Id);

私は言ってエラーが出ます:

No IUserTokenProvider is registered.

今のところ、それがどのようなコードを生成するのかを見たかっただけです。ApplicationUserクラスから継承する変更をクラスに加える必要がありIdentityUserますか?

または、これらの関数を機能させるために変更する必要があるものはありますか?


1
メールアドレス以外のフィールドに基づいてユーザーが存在するかどうかを確認する方法はありますか?たとえば、すでにデータベースに存在しているユーザーのためにCustomerNumberとPostcodeという2つのフィールドがあり、誰でも登録できないようにする場合
Jay

回答:


127

UserTokenProviderトークンを生成するには、を指定する必要があります。

using Microsoft.Owin.Security.DataProtection;
using Microsoft.AspNet.Identity.Owin;
// ...

var provider = new DpapiDataProtectionProvider("SampleAppName");

var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>());

userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(
    provider.Create("SampleTokenName"));

ASP.NET IDを使用してアプリケーションに2要素認証を追加するも読んでください。


5
"Sample""EmailConfirmation"?何かをすることができるいくつかのテキスト?
Cyber​​cop 2014年

2
"Sample" = AppName、 "EmailConfirmation" =目的(パラメーター名など)
meziantou

5
はい。ただし、トークンの生成と検証には同じものを使用する必要があります
meziantou

1
リンクはOKです。このコードを初期化する場所に配置しますUserManager
meziantou 2014

これにより、.netcoreのアセンブリから「タイプ「System.Security.Cryptography.DpapiDataProtector」をロードできませんでした
TAHA SULTAN TEMURI '12

25

ASP.NET Coreでは、次のように、Startup.csでデフォルトサービスを構成できるようになりました。

services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddDefaultTokenProviders();

DpapiDataProtectionProviderまたはそのようなものを呼び出す必要はありません。DefaultTokenProviders()は、UserManagerからのGenerateEmailConfirmationTokenの呼び出しを処理します。


21

受け入れられた回答に加えて、このアプローチはAzure Webサイトでは機能せず、トークンの代わりにCryptographicExceptionが発生することを付け加えておきます。

Azure用に修正するには、独自のIDataProtectorを実装します。この回答を参照してください

ブログ投稿のやや詳細


13

私の解決策:

    var provider = new DpapiDataProtectionProvider("YourAppName");
    UserManager.UserTokenProvider = new DataProtectorTokenProvider<User, string>(provider.Create("UserToken")) 
        as IUserTokenProvider<User, string>;

このコードの私の問題は解決しました。
幸運の友達。


Microsoft.Owin.Security.DataProtectionを使用します。
アミンガデリ2014年

両方のジェネリックに対して、<User、string>の代わりにDataProtectorTokenProvider <IdentityUser、string>を使用する必要がありました。また、GeneratePasswordResetTokenのuserIdは、GUID文字列IDであり、userNameやEmailではありません。
Dan Randolph、2017年

7

他の誰かが私と同じ過ちを犯した場合に備えて。以下のような関数を作ってみましたが、「IUserTokenProviderが登録されていません。行ってしまった。しかし、「callbackUrl」から生成されたリンクを使用しようとするとすぐに、「無効なトークン」というエラーが発生しました。これを機能させるには、HttpContext UserManagerを取得する必要があります。個別のユーザーアカウントで標準のASP.NET MVC 5アプリケーションを使用している場合は、以下のように実行できます。

機能するコード:

public ActionResult Index()
     {
         //Code to create ResetPassword URL
         var userManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
         var user = userManager.FindByName("useremail@gmail.com");
         string code = userManager.GeneratePasswordResetToken(user.Id);
         var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
         return View();
     }

うまくいかない最初の試みNo IUserTokenProvider is registered.はなくなりましたが、作成されたURLは取得されますInvalid token.

public ActionResult NotWorkingCode()
     {
             //DOES NOT WORK - When used the error "Invalid token." will always trigger.
             var provider = new DpapiDataProtectionProvider("ApplicationName");
             var userManager = new ApplicationUserManager(new UserStore<ApplicationUser>(new ApplicationDbContext()));
             userManager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(provider.Create("ASP.NET Identity"));
             var user = userManager.FindByName("useremail@gmail.com");
             string code = userManager.GeneratePasswordResetToken(user.Id);
             var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
             //DOES NOT WORK - When used the error "Invalid token." will always trigger.
         return View();
     }

5

上記のpiskerに従って

startup.csで使用できます

services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddDefaultTokenProviders();

.net core 2.0では、startup.csに追加する必要がある場合があります。

using Microsoft.AspNetCore.Identity;

これは私にとってはうまくいきました。


1
これはAsp .NET Coreソリューションであり、Asp .NET Frameworkでは機能しないことを覚えておくことは重要だと思います。
マチャド

2

.NET CoreのIDファイルを変更しているときに、このエラーに遭遇しました。

NotSupportedException:「Default」という名前のIUserTwoFactorTokenProviderが登録されていません。

Microsoft.AspNetCore.Identity.UserManager.GenerateUserTokenAsync

新しいユーザーの登録時に利用可能なプロバイダーがなかったため、関数はトークンを生成できませんでした。このエラーは簡単に修正できます!

私のようであればAddDefaultIdentityStartup.csファイルをに変更しましたAddIdentity。ベースユーザーから継承した自分のユーザーを実装したかった。これにより、デフォルトのトークンプロバイダーが失われました。修正はそれらをで追加し直すことでしたAddDefaultTokenProviders()

        services.AddIdentity<User, UserRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

その修正後、すべてが再び機能しました!

ソース:https : //mattferderer.com/NotSupportedException-No-IUserTwoFactorTokenProvider-tuser-named-default-registered


1

Identityを更新した後も同じエラーが発生し、Unityを使用していたことが原因であることがわかりました。

ソリューションのこの質問スレッドを参照してください: UnityにIAuthenticationManagerを登録します

以下もクイックリファレンスです:

UnityをASP.NET Identity 2.0でうまく機能させるために私が行ったのは次のとおりです。

クラスのRegisterTypesメソッドに以下を追加しましたUnityConfig

container.RegisterType<DbContext, ApplicationDbContext>(new HierarchicalLifetimeManager());
container.RegisterType<UserManager<ApplicationUser>>(new HierarchicalLifetimeManager());
container.RegisterType<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>(new HierarchicalLifetimeManager());
container.RegisterType<AccountController>(new InjectionConstructor());

1
私はこれに従いましGeneratePasswordResetTokenたが、機能しませんでした(for-しかし、「IUserTokenProviderが登録されていません」という同じエラーが発生しました)。に追加container.RegisterType<ApplicationUserManager>( new InjectionFactory(c => HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>()));した後UnityConfig.cs、機能しました。


0

IdentityConfig.csで、2要素オプションを追加します。

        manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser>
        {
            MessageFormat = "Your security code is {0}"
        });
        manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider<ApplicationUser>
        {
            Subject = "Security Code",
            BodyFormat = "Your security code is {0}"
        });
        //config sms service 
        manager.SmsService = new Services.SMS();
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.