web-dev-qa-db-ja.com

OWIN / Katanaを使用したAzureでのデータ保護操作は失敗しました

Azureで実行されているOWIN /カタナベースのASP.NET MVC Webサイトにパスワードリセットを実装しようとしています。

ローカルで実行すると正常に機能しますが、本番環境では失敗します。

UserTokenプロバイダーを作成します

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

しかし、次のようにトークンを生成しようとすると

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

次の例外が発生します。

System.Security.Cryptography.CryptographicException:データ保護操作は失敗しました。これは、現在のスレッドのユーザーコンテキストに対してユーザープロファイルが読み込まれていないことが原因である可能性があります。これは、スレッドが偽装している場合に発生することがあります。 System.Security.Cryptography.DataProtector.ProtectでSystem.Security.Cryptography.DpapiDataProtector.ProviderProtect(Byte [] userData)でSystem.Security.Cryptography.ProtectedData.Protect(Byte [] userData、Byte [] optionalEntropy、DataProtectionScope scope)で(Byte [] userData)at Microsoft.Owin.Security.DataProtection.DpapiDataProtector.Protect(Byte [] userData)at Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider 2.d__0.MoveNext()---前のスタックトレースの終わり例外がスローされた場所--- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at Microsoft.AspNet.Identity.UserManager`2.d__e9.MoveNext ()

22
Mat Guthrie

Web APIでASP .Net IDとカスタムログイン関数を使用してトークンを生成しようとすると、同じ問題が発生します。

「データ保護操作に失敗しました。これは、現在のスレッドのユーザーコンテキストにユーザープロファイルが読み込まれていないことが原因である可能性があります。これは、スレッドが偽装している場合に発生することがあります。」

私がしたことは、単にMicrosoft AzureでWEBSITE_LOAD_USER_PROFILEというアプリケーション設定を作成し、それを1に設定することです。そのソリューションは私にとってうまくいきます。

詳細はこちら こちら

12
Satria Janaka

この質問に対する私の 私の答え をご覧ください。 IAppBuilder.GetDataProtectionProvider()を使用することで、はるかに簡単なソリューションを実現できます。

5
Loren Paulsen

解決策を見つけました。それが機能するためにすべての手順が必要かどうかは正確にはわかりませんが、私のアプリは完全に機能します:

1.- web.configを更新して、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"/>

configSectionsノード内。そして

  <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>

通常のノードとして。 2.- Startup.Auth.csファイルで、ConfigureAuth(IAppBuilder app)を次のように更新します。

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.-次のように、スタートアップクラスのコンストラクタをクリーンアップします。

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

それは私のために働いた:)私はそれがあなたのためにも働くことを望みます

4
JLuis Estrada

ホストサーバーが仮想マシンの場合は、エラーメッセージのとおりです。 IISのアプリケーションプールに実際にLoad User Profile例外のようにtrueに設定:

  • [接続]ウィンドウでサーバー名を展開し、[アプリケーションプール]をクリックします。
  • あなたのプールを右クリック
  • 高度な設定

enter image description here

4
Ogglas

これをしばらく氷の上に置いたのですが、また戻さざるを得ませんでした。私はここに解決策を見つけました: リセットパスワードトークンの生成はAzure Webサイトでは機能しません

2
Mat Guthrie

このエラーは、共有ホスティングプロバイダーで次の行で発生します。

var provider = new DpapiDataProtectionProvider("SITENAME");

解決策は非常に簡単でした。まず、上記の行を次のように変更します。

var provider = new MachineKeyProtectionProvider();

次に、次のように、Utilities名前空間にある新しいファイルを作成します。

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);
        }
    }
}

出来上がり!問題が解決しました。覚えておいてください。パスワードリセットコントローラーメソッドでは、このプロバイダーも使用する必要があります。そうしないと、Invalid Tokenエラー。

2
Sean

App_Start/Startup.Auth.csで設定されているように、OwinパイプラインからUserManagerを取得すると、Azureで機能します。これが具体的にどのように機能するかはわかりません。 DpApiは、最初のリンクで説明されているソリューションを使用してAzureで動作するはずです。

DpApiの静的マシンキーがWeb.configに設定されている場合、すべてのサーバーマシンは、Webファーム内の別のマシンによって作成された暗号化データを復号化できます。

(標準テンプレートで指定されているコード-AccountController.csから)

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