8
respostas

Erro IUserTokenProvider

Bom dia. Não sei porque motivo minha dúvida foi marcada como solucionada, mas ainda não cheguei na solução.

Estou abrindo novamente, para que alguém possa me ajudar. O Marcelo estava me ajudando, mas ainda não consegui êxito. Tenho o seguinte código de Esqueci minha Senha:

[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task EsqueciSenha(EsqueciSenhaViewModel modelo) { if (!ModelState.IsValid) { return View(modelo); }

            var provider = new DpapiDataProtectionProvider("ASP.NET Identity");
        UserManager.UserTokenProvider = new DataProtectorTokenProvider<Usuario, string>(
               provider.Create("UserToken"));

                    var usuario = await UserManager.FindByEmailAsync(modelo.Email);

        if (usuario == null || !(await UserManager.IsEmailConfirmedAsync(usuario.Id)))
        {
           return View("ConfirmacaoEsqueciSenha");
        }

        var token = await UserManager.GeneratePasswordResetTokenAsync(usuario.Id);
        var callbackUrl = Url.Action("ConfirmacaoEsqueciSenha", "Autenticacao", new { UsuarioId = usuario.Id, Token = token }, protocol: Request.Url.Scheme);
        var enviarEmail = EmailEsqueciSenhaController.EnviarEmail(usuario, "Por favor redefina sua senha clicando aqui: <a href=\"" + callbackUrl + "\">Redefinir sua senha!</a>", "Alteração de senha");
        return View("EmailEsqueciSenhaEnviado");
    }

No código acima está tudo ok, recebo o usuario e o token na URL e recebo um e-mail com link para confirmar a alteração, ao clicar neste link sou redirecionada para o código abaixo:

[HttpPost] public async Task ConfirmacaoEsqueciSenha(ConfirmacaoEsqueciSenhaViewModel modelo) { if (ModelState.IsValid) { // Verifica o Token recebido // Verifica o ID do usuário // Mudar a senha var resultadoAlteracao = await UserManager.ResetPasswordAsync( modelo.UsuarioId, modelo.Token, modelo.NovaSenha);

        if (resultadoAlteracao.Succeeded)
        {
            return RedirectToAction("Index", "Home");
        }

        AddErrors(resultadoAlteracao);

}

    return View();

} Neste código que ocorre o erro. Segue abaixo o erro que ocorre:

No IUserTokenProvider is registered. Descrição: Ocorreu uma exceção sem tratamento durante a execução da atual solicitação da Web. Examine o rastreamento de pilha para obter mais informações sobre o erro e onde foi originado no código.

Detalhes da Exceção: System.NotSupportedException: No IUserTokenProvider is registered.

Erro de Origem:

Linha 353: // Verifica o ID do usuário Linha 354: // Mudar a senha Linha 355: var resultadoAlteracao = Linha 356: await UserManager.ResetPasswordAsync( Linha 357: modelo.UsuarioId,

É como se o usuário não estivesse registrado. Sabem o que pode ser?

Obrigada. Flávia Lares

8 respostas

Oi Marcelo. Abri uma outra postagem , pois a outra não sei porque motivo foi colocada como solucionada. Continuo com erro no código Esqueci Senha se puder me ajudar.

Obrigada.

Flávia Lares

Oi pessoal.

Ainda não obtive uma solução , se alguém puder me ajudar ficarei muito grata.

Flávia

Oi Flávia, tudo bem? Sinto muito pelo inconveniente, não me lembro se fui eu que marquei o post como solucionado por engano. Seu projeto está no GitHub? Se estiver, pode postar o link aqui? Se não estiver, por favor mande o zip do projeto para o meu email marcelo.oliveira@alura.com.br. Obrigado!

Oi Marcelo.

Meu projeto não está no GitHub pois esta parte está embutida em um projeto gigante. Não teria como disponibilizar, mas se puder me ajudar ficarei muito grata.

Agora estou com o seguinte problema:

Assim que o e-mail é enviado o projeto pára a execução e ocorre a seguinte exceção:

System.Transactions Critical: 0 : http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/UnhandledExceção não tratada/LM/W3SVC/2/ROOT-1-132042163787937675System.NullReferenceException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089Referência de objeto não definida para uma instância de um objeto. em System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext) em System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext) em System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state) em System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state) em System.Web.LegacyAspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state) em System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction(Object state) em System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task&amp; currentTask) --- Fim do rastreamento de pilha do local anterior onde a exceção foi gerada ---

Sendo que o e-mail com a alteração de senha é enviado e se eu rodar novamente o sistema e tentar efetuar a troca, ao clicar no botão Alterar ocorre o seguinte erro:

No IUserTokenProvider is registered. Descrição: Ocorreu uma exceção sem tratamento durante a execução da atual solicitação da Web. Examine o rastreamento de pilha para obter mais informações sobre o erro e onde foi originado no código.

Detalhes da Exceção: System.NotSupportedException: No IUserTokenProvider is registered.

Erro de Origem:

Linha 324: // Mudar a senha Linha 325: Linha 326: var resultadoAlteracao = Linha 327: await UserManager.ResetPasswordAsync( Linha 328: modelo.UsuarioId,

A configuração do DataProtectionProvider está sendo feita no método Create() do UsuarioManager, assim:

public static UsuarioManager Create()

    {

        var userStore = new UserStore<Usuario>(new IgsContext());

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

         var dataProtectorProvider = IdentityConfig.DataProtectionProvider;
        var dataProtector = dataProtectorProvider.Create("UserToken");
        userManager.UserTokenProvider = new DataProtectorTokenProvider<Usuario>(dataProtector)
        {
            TokenLifespan = TimeSpan.FromHours(24)
        };
        return new UsuarioManager(userStore);

    }

O erro de nulo ocorre aqui.

Desde já agradeço. Flávia Lares

Oi Flávia,

Seu projeto usa ASP.NET Core? Se for, por favor verifique se está usando o método AddDefaultTokenProviders na classe Startup:

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

Oi Marcelo. Não utilizo o Asp.Net Core. Utilizo o asp.net framework 4.5.2. Neste caso não tenho a classe Startup, utilizo a classe IdentityConfig, nesta coloquei a seguinte configuração:

public static IDataProtectionProvider DataProtectionProvider { get; set; }

    public void Configuration(IAppBuilder app)
    {

DataProtectionProvider = app.GetDataProtectionProvider(); }

Talvez esteja faltando algo nesta configuração.

Obrigada. Flávia

Oi Flávia

Agora notei que você está instanciando diretamente o UserManager com o operador new;

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

Pelo que li em alguns fóruns, o correto seria receber essa instância através de injeção de dependência no seu controller, assim:

public MeuController()
{
    private readonly UserManager<Usuario> userManager;

    public MeuController(UserManager<Usuario> userManager)
    {
        this.userManager = userManager;
    }    
    .
    .
    .
}

Por favor, veja se funciona. Obrigado!

Oi Marcelo.

No meu controller estou fazendo assim:

private UsuarioManager usuarioManager;

public UsuarioManager UserManager { get { return usuarioManager ?? HttpContext.GetOwinContext().GetUserManager(); } private set { usuarioManager = value; } }

Devo mudar esta forma e passar como parâmetro no Controller?

Obrigada. Flávia