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라는 두 개의 필드가있는 경우 등록을 중지하기 위해
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"? 무엇이든 될 수있는 텍스트?
Cybercop 2014 년

2
"샘플"= 프로그램 응용, (매개 변수 이름과 같은) "EmailConfirmation"= 목적
meziantou

5
네,하지만 당신은 생성하고 토큰의 유효성을 확인하는 동일한을 사용해야합니다
meziantou을

1
링크는 괜찮습니다. 당신이 초기화하는 UserManager
곳에이

이로 인해 .netcore의 어셈블리에서 'System.Security.Cryptography.DpapiDataProtector'유형을로드 할 수 없습니다.
TAHA SULTAN TEMURI

25

ASP.NET Core에서는 이제 다음과 같이 Startup.cs에서 기본 서비스를 구성 할 수 있습니다.

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

에게 전화 할 필요가 없습니다 DpapiDataProtectionProvider. DefaultTokenProviders ()는 UserManager에서 GenerateEmailConfirmationToken에 대한 호출을 처리합니다.


21

허용되는 답변 외에도이 접근 방식이 Azure 웹 사이트에서 작동하지 않으며 토큰 대신 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 사용;
아민 Ghaderi

두 제네릭 모두에 대해 <User, string> 대신 DataProtectorTokenProvider <IdentityUser, string>을 사용해야했습니다. 또한 GeneratePasswordResetToken의 userId는 userName 또는 Email이 아니라 guid 문자열 Id입니다.
Dan Randolph

7

다른 사람이 저와 같은 실수를했을 경우를 대비해 아래의 함수를 만들려고했는데 "IUserTokenProvider가 등록되지 않았습니다."라는 오류가 충분히 발생했는지 확인했습니다. 사라졌다. 그러나 "callbackUrl"에서 생성 된 링크를 사용하려고하면 "Invalid token"이라는 오류가 발생했습니다. 작동하려면 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에서는 작동하지 않습니다.
Machado

3

.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 등록

또한 빠른 참조를 위해 아래 :

ASP.NET Identity 2.0에서 Unity를 멋지게 만들기 위해 제가 한 작업은 다음과 같습니다.

클래스 의 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그러나 "No IUserTokenProvider is registered"라는 동일한 오류가 발생했습니다). 추가 한 후 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.