簡體   English   中英

使用 OWIN / Katana 在 Azure 上進行數據保護操作不成功

[英]The data protection operation was unsuccessful on Azure using OWIN / Katana

我正在嘗試在運行於 Azure 的基於 OWIN/Katana 的 ASP.NET MVC 網站上實施密碼重置。

它在本地運行時工作正常但在生產中失敗。

我創建了一個 UserToken Provider

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

但是當我嘗試如下生成令牌時

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

我得到以下異常。

System.Security.Cryptography.CryptographicException:數據保護操作不成功。 這可能是由於沒有為當前線程的用戶上下文加載用戶配置文件造成的,這可能是線程正在模擬時的情況。 在 System.Security.Cryptography.ProtectedData.Protect(Byte[] userData, Byte[] optionalEntropy, DataProtectionScope 范圍) 在 System.Security.Cryptography.DpapiDataProtector.ProviderProtect(Byte[] userData) (Byte[] userData) at Microsoft.Owin.Security.DataProtection.DpapiDataProtector.Protect(Byte[] userData) at Microsoft.AspNet.Identity.Owin.DataProtectorTokenProvider 2.d__0.MoveNext() --- 上一個堆棧跟蹤結束引發異常的位置 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任務任務) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任務任務) 在 Microsoft.AspNet.Identity.UserManager`2.d__e9.MoveNext ()

當我嘗試在Web API中使用ASP .Net標識和自定義登錄功能生成令牌時,我遇到了同樣的問題。

“數據保護操作不成功。這可能是由於沒有為當前線程的用戶上下文加載用戶配置文件引起的,這可能是線程模擬時的情況。”

我所做的只是在Microsoft Azure中創建一個名為WEBSITE_LOAD_USER_PROFILE的應用程序設置,並將其設置為1.該解決方案適用於我。

你可以在這里看到細節

請看我對這個問題的答案 利用IAppBuilder.GetDataProtectionProvider()可以實現更簡單的解決方案

我找到了解決方案。 我不確定是否所有步驟都是必要的,但現在我的應用程序完美運行:

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應用程序),如下所示:

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.-像這樣清理你的Startup類的構造函數:

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

這對我有用:)我希望它也適合你

如果主機服務器是虛擬機,則可能正是錯誤消息所說的內容。 檢查IIS中的應用程序池是否確實將“ Load User Profile設置為“true”,如下所示:

  • 在“連接”窗格中,展開服務器名稱,然后單擊“應用程序池”。
  • 右鍵單擊您的池
  • 高級設置

在此輸入圖像描述

我把這個放在冰上一段時間,但被迫回到它。 我在這里找到了解決方案: 生成重置密碼令牌在Azure網站中不起作用

我在共享主機提供商處發生此錯誤,該行:

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錯誤。

從Owin管道獲取UserManager,就像它在App_Start / Startup.Auth.cs中的設置一樣,適用於Azure。 我不確定這是如何具體的。 DpApi應該在Azure中使用第一個鏈接中描述的解決方案。

如果DpApi在Web.config中設置了靜態機器密鑰,則所有服務器機器都能夠解密由webfarm中的另一台機器創建的加密數據。

(標准模板中給出的代碼 - 來自AccountController.cs)

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

在我和其他兩個人弄亂了 dayS 的這個錯誤之后,我們在 IIS 中發現了一些有趣的東西。如果切換了加載用戶配置文件,則會在 applicationhost.config 中創建以下內容

loadUserProfile="true"

但是當你關閉它時它也可以工作,但是現在這條線

loadUserProfile="false"

已添加。 所以區別在於必須在 applicationhost.config 中寫入默認值才能使其工作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM