我正在使用WIF(.net 4.5)和Azure Active目录进行身份验证。该网站将位于Azure上。
一切都在本地工作,但是当我把它放到azure上时,我得到错误:
数据保护操作失败。这可能是由于没有为当前线程的用户上下文加载用户配置文件引起的,这可能是线程模拟时的情况。
我理解这是因为应用无法使用DAPI,因此我需要切换到使用MAC保护我的应用。
在本地我将其添加到我的webconfig: -
<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" />
</securityTokenHandlers>
按照documentation的建议,我添加了一个静态机器密钥,但我找不到关于密钥长度的任何建议 - 所以我假设256。
然而,此配置只会出现此错误:
[CryptographicException:加密操作期间发生错误。] System.Web.Security.Cryptography.HomogenizingCryptoServiceWrapper.HomogenizeErrors(Func`2 func,Byte [] input)+115 System.Web.Security.Cryptography.HomogenizingCryptoServiceWrapper.Unprotect(Byte [] protectedData)+59 System.Web.Security.MachineKey.Unprotect(ICryptoServiceProvider cryptoServiceProvider,Byte [] protectedData,String []用途)+62 System.Web.Security.MachineKey.Unprotect(Byte [] protectedData,String []用途)+122 System.IdentityModel.Services.MachineKeyTransform.Decode(Byte [] encoded)+161 System.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte [] cookie,Boolean outbound)+123 System.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader,SecurityTokenResolver tokenResolver)+575 System.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte [] token,SecurityTokenResolver tokenResolver)+76 System.IdentityModel.Services.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte [] sessionCookie)+833 System.IdentityModel.Services.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken&amp; sessionToken)+186 System.IdentityModel.Services.SessionAuthenticationModule.OnAuthenticateRequest(Object sender,EventArgs eventArgs)+210 System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+136 System.Web.HttpApplication.ExecuteStep(IExecutionStep step,Boolean&amp; completedSynchronously)+69
我删除了machinekey部分,因为我没有指定格式正确的密钥,但错误不会消失。
战斗WIF真是太棒了!
答案 0 :(得分:48)
如果未在配置中指定machineKey,则Azure会添加一个。但是,如果您使用VIP切换创建应用程序的新版本并将其部署到Azure,则Azure会为Staging中的部署生成新计算机密钥(假设您的第一次部署是生产)。 (VIP切换是部署新版本然后在生产和暂存之间切换虚拟IP地址的好机制。)
所以基本上一个解决方案就是让Azure生成密钥,但在VIP切换后你就会遇到问题。为了避免它,您可以在Application_Error处理程序中捕获Global.asax中的CryptographicException,如下所示:
// Be sure to reference System.IdentityModel.Services
// and include using System.IdentityModel.Services;
// at the start of your class
protected void Application_Error(object sender, EventArgs e)
{
var error = Server.GetLastError();
var cryptoEx = error as CryptographicException;
if (cryptoEx != null)
{
FederatedAuthentication.WSFederationAuthenticationModule.SignOut();
Server.ClearError();
}
}
SignOut()方法导致cookie被删除。
修改:有关生成machineKey的更新信息,如@anjdreas所述。
另一个解决方案是生成machineKey,您可以使用IIS管理器执行此操作,有关详细信息,请参阅Easiest way to generate MachineKey。如果将相同的密钥放入Azure Web角色中的所有Web应用程序中,则Azure部署过程不会替换它。
答案 1 :(得分:3)
机器密钥不应该存在:Windows Azure为您生成一个密钥,并确保它在您的角色中的每个实例上都相同。
关于您看到的错误:您可以尝试清除Cookie吗?
答案 2 :(得分:2)
在这种情况下,简单地清除cookie就解决了整个问题。
答案 3 :(得分:0)
如果您使用的是表单身份验证。您可以在捕获异常时注销,并允许您的用户登录并创建有效的cookie
catch (CryptographicException cex)
{
FormsAuthentication.SignOut();
}
答案 4 :(得分:-2)
要求所有用户清除所有Cookie对我来说真的不是一个选择。在this site以及书籍#34;编程Windows身份联合会&#34;我找到了一个更好的解决方案(对我而言,无论如何)。如果您已经将SSL证书上载到Azure,则可以使用该证书在所有Azure实例上加密Cookie,并且您不必担心新的计算机密钥,IIS用户配置文件等。