Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
416 views
in Technique[技术] by (71.8m points)

asp.net - Federated Authentication on Azure

I'm using WIF (.net 4.5), and Azure Active directory for authentication. The website will sit on Azure.

Everything works as expected locally, however when I put it onto azure I get the error:

The data protection operation was unsuccessful. This may have been caused by not having the user profile loaded for the current thread's user context, which may be the case when the thread is impersonating.

I understand this is because the apps can't use DAPI, so I need to switch to protecting my app with the MAC.

Locally I added this to my 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>

as recommended in the documentation, and I added a static machine key, but I can't find any advice around the key length - so I have assumed 256.

This configuration however just gives this error:

[CryptographicException: Error occurred during a cryptographic operation.] 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[] purposes) +62 System.Web.Security.MachineKey.Unprotect(Byte[] protectedData, String[] purposes) +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& 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& completedSynchronously) +69

I removed the machinekey section incase I hadn't specified a correctly formatted key, but the error doesn't go away.

What a fight WIF has been!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you don't specify machineKey in configuration, Azure adds one. But if you create new version of your application and deploy it to Azure using VIP switching, Azure generates a new machine Key for the deployment in Staging (assuming your first deployment was to Production). (VIP switching is nice mechanism for deploying new version and then switching virtual IP addresses between Production and Staging).

So basically one solution is letting Azure to generate the key but after VIP switch you have the problem back. To avoid it you can catch the CryptographicException in Global.asax in Application_Error handler, something like this:

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

The SignOut() method causes the cookie is removed.

Edit: updated info on generating machineKey as noted by @anjdreas.

Another solution is to generate the machineKey, you can use IIS Manager to do it, see Easiest way to generate MachineKey for details. If you put the same key into all your web appliactions within Azure Web Role, the Azure deployment process will not replace it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...