web-dev-qa-db-fra.com

L'opération de protection des données a échoué sur Azure avec OWIN/Katana.

J'essaie d'implémenter la réinitialisation du mot de passe sur un site Web ASP.NET MVC basé sur OWIN/Katana qui s'exécute dans Azure.

Il fonctionne bien lorsqu'il est exécuté localement mais échoue en production.

Je crée un fournisseur UserToken

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

Mais quand j'essaie de générer le jeton comme suit 

var resetToken = await UserManager.GeneratePasswordResetTokenAsync(user.Id);

Je reçois l'exception suivante.

System.Security.Cryptography.CryptographicException: Les données l'opération de protection a échoué. Cela peut avoir été causé par ne pas avoir le profil d'utilisateur chargé pour l'utilisateur du thread actuel contexte, ce qui peut être le cas lorsque le thread emprunte l'identité de . sur System.Security.Cryptography.ProtectedData.Protect (Byte [] userData, Byte [] optionalEntropy, portée de DataProtectionScope) sur System.Security.Cryptography.DpapiDataProtector.ProviderProtect (Byte [] userData) sur System.Security.Cryptography.DataProtector.Protect (Byte [] userData) sur Microsoft.Owin.Security.DataProtection.DpapiDataProtector.Protect (Byte [] userData) sur Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider 2.d__0.MoveNext () --- Trace de fin de pile depuis l'emplacement précédent où une exception a été levée --- sur System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (tâche tâche) à System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task tâche). chez Microsoft.AspNet.Identity.UserManager`2.d__e9.MoveNext ()

18
Mat Guthrie

J'ai le même problème lorsque j'essaie de générer un jeton avec ASP. Identité Net et fonction de connexion personnalisée dans l'API Web. 

"L'opération de protection des données a échoué. Cela peut avoir été provoqué par le fait que le profil utilisateur n'a pas été chargé pour le contexte utilisateur Du thread actuel, ce qui peut être le cas lorsque le thread se fait passer pour une identité."

Ce que j'ai fait est simplement de créer un paramètre d'application appelé WEBSITE_LOAD_USER_PROFILE dans Microsoft Azure et de le définir sur 1. Cette solution fonctionne pour moi.

Vous pouvez voir le détail ici

9
Satria Janaka

S'il vous plaît voir mon ma réponse à cette question. Une solution beaucoup plus simple peut être obtenue en utilisant IAppBuilder.GetDataProtectionProvider()

5
Loren Paulsen

J'ai trouvé une solution. Je ne sais pas exactement si toutes les étapes sont nécessaires pour que cela fonctionne, mais maintenant, mon application fonctionne parfaitement:

1.- Mettez à jour votre web.config pour prendre en charge securityTokenHandlers

<section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>

dans le noeud configSections. Et

 

  <securityTokenHandlers>
    <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler,
                System.IdentityModel, Version=4.0.0.0, Culture=neutral,
                PublicKeyToken=B77A5C561934E089" />

    <add
      type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler,
          System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral,
          PublicKeyToken=B77A5C561934E089">
      <sessionTokenRequirement lifetime="00:30:00"></sessionTokenRequirement>
    </add>
  </securityTokenHandlers>

</identityConfiguration>

en tant que noeud normal . 2.- Dans votre fichier Startup.Auth.cs, mettez à jour votre ConfigureAuth (application IAppBuilder) comme suit:

public void ConfigureAuth(IAppBuilder app)
        {

            UserManagerFactory = () =>
            {
                var userManager = new UserManager<SIAgroUser>(new UserStore<UserType>(new SIAgroUserDbContext()));

                IDataProtectionProvider provider = app.GetDataProtectionProvider();

                //userManager.UserTokenProvider = new Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider<UserType>(provider.Create("PasswordReset") );
                if (provider != null)
                {
                    userManager.UserTokenProvider = new DataProtectorTokenProvider<UsertType, string>(provider.Create("PasswordReset"));
                }

                return userManager;
            };

            OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/Token"),
                Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory),
                AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                AllowInsecureHttp = true
            };
            // Enable the application to use a cookie to store information for the signed in user
            // and to use a cookie to temporarily store information about a user logging in with a third party login provider
            app.UseCookieAuthentication(new CookieAuthenticationOptions());
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            // Enable the application to use bearer tokens to authenticate users
            app.UseOAuthBearerTokens(OAuthOptions);

            // Uncomment the following lines to enable logging in with third party login providers
            //app.UseMicrosoftAccountAuthentication(
            //    clientId: "",
            //    clientSecret: "");

            //app.UseTwitterAuthentication(
            //    consumerKey: "",
            //    consumerSecret: "");

            //app.UseFacebookAuthentication(
            //    appId: "",
            //    appSecret: "");

            //app.UseGoogleAuthentication();



        }

3.- Nettoyez le constructeur de votre classe de démarrage comme ceci:

static Startup()
{
   PublicClientId = "self";
}

Cela a fonctionné pour moi :) J'espère que cela fonctionne pour vous aussi

4
JLuis Estrada

J'ai mis celui-ci sur la glace pendant un moment, mais j'ai été obligé d'y revenir. J'ai trouvé la solution ici: La génération d'un jeton de réinitialisation du mot de passe ne fonctionne pas dans le site Web Azure

2
Mat Guthrie

Cette erreur se produit pour moi sur un fournisseur d'hébergement partagé, à la ligne:

var provider = new DpapiDataProtectionProvider("SITENAME");

La solution était assez simple. Commencez par changer la ligne ci-dessus en ceci:

var provider = new MachineKeyProtectionProvider();

Ensuite, créez un nouveau fichier, que j'ai dans mon espace de noms Utilities, comme suit:

using Microsoft.Owin.Security.DataProtection;
using System.Web.Security;

namespace <yournamespace>.Utilities
{
    public class MachineKeyProtectionProvider : IDataProtectionProvider
    {
        public IDataProtector Create(params string[] purposes)
        {
            return new MachineKeyDataProtector(purposes);
        }
    }

    public class MachineKeyDataProtector : IDataProtector
    {
        private readonly string[] _purposes;

        public MachineKeyDataProtector(string[] purposes)
        {
            _purposes = purposes;
        }

        public byte[] Protect(byte[] userData)
        {
            return MachineKey.Protect(userData, _purposes);
        }

        public byte[] Unprotect(byte[] protectedData)
        {
            return MachineKey.Unprotect(protectedData, _purposes);
        }
    }
}

Et voilà! Problème résolu. N'oubliez pas que dans votre méthode de contrôleur de réinitialisation de mot de passe, vous devrez également utiliser ce fournisseur, sinon vous obtiendrez une erreur Invalid Token.

2
Sean

Si le serveur hôte est une machine virtuelle, il est possible que le message d'erreur corresponde exactement. Vérifiez si votre pool d'applications dans IIS a vraiment Load User Profile défini sur true, comme le dit l'exception:

 enter image description here

2
Ogglas

L'obtention de UserManager à partir du pipeline Owin, telle qu'elle est définie dans App_Start/Startup.Auth.cs, fonctionne sur Azure. Je ne sais pas comment cela fonctionne spécifiquement. DpApi doit fonctionner dans Azure avec la solution décrite dans le premier lien.

Si le fichier DpApi a une clé de machine statique définie dans Web.config, tous les ordinateurs du serveur seront en mesure de décrypter les données cryptées créées par un autre ordinateur de votre parc Web. 

(code comme indiqué dans le modèle standard - de AccountController.cs)

 private UserManager userManager;
    public UserManager UserManager
    {
        get { return userManager ?? HttpContext.GetOwinContext().GetUserManager<UserManager>(); }
        private set { userManager = value; }
    }
0
WarrenDodsworth