locked
F.A.M. Error / System.Security.Cryptography.CryptographicException: The system cannot find the file specified RRS feed

  • Question

  • Encountered an interesting problem when the F.A.M. / Relying Party tries to process the SecurityToken Post Back from the STS.   If I don't use ASP.NET impersonation the token is decrypted fine without error.   I believe the Network Service Account is used in this context   If I turn on asp.net impersonation and set it to a user that is a local admin on the box, the F.A.M. spits out this exception:

    "System.Security.Cryptography.CryptographicException: The system cannot find the file specified.\r\n\r\n   at System.Security.Cryptography.ProtectedData.Protect(Byte[] userData, Byte[] optionalEntropy, DataProtectionScope scope)\r\n   at Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Encode(Byte[] value)\r\n   at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte[] cookie, Boolean outbound)\r\n   at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.Serialize(SessionSecurityToken sessionToken)\r\n   at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.WriteToken(XmlWriter writer, SecurityToken token)\r\n   at Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.WriteToken(SessionSecurityToken sessionToken)\r\n   at Microsoft.IdentityModel.Web.FederatedAuthenticationModuleBase.SetPrincipalAndWriteSessionToken(SessionSecurityToken sessionToken, Boolean isSession)\r\n   at Microsoft.IdentityModel.Web.FederatedAuthenticationModuleBase.AuthenticationCore
    ()\r\n   at Microsoft.IdentityModel.Web.WSFederationAuthenticationModule.AuthenticationCore()\r\n   at Microsoft.IdentityModel.Web.FederatedAuthenticationModuleBase.OnAuthenticateRequest(Object sender, EventArgs args)\r\n   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()\r\n   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)"

    I believe the F.A.M. is puking because it can't open the cert required to decrypt the Security Token.  This particular cert is in Local Machine / My.
    The odd thing is that the ASP.NET impersonated user is a local admin of the box but can't open that cert.   Has anyone else run into this problem?   

    thanks!



    B.T.W.   Thats a very non helpful exception.





    Saturday, May 9, 2009 2:29 AM

Answers

  • Try login on to the machine using the account you are impersonating. That should create the profile for the first time. Alternatively you can do it with code with the API mentioned above, but I believe login the user will work.

    In any case in a production environment you don't want to use the ProtectedCookie transform because it won't work with web farms (profiles and master keys will be different in server 1 and server 2). 


    Matias Woloski - http://blogs.southworks.net/mwoloski - southworks
    • Marked as answer by scott_m Sunday, May 10, 2009 2:54 AM
    Sunday, May 10, 2009 1:36 AM

All replies

  • What the FAM is trying to do is to encrypt the ClaimsPrincipal with DPAPI to store it later in a cookie. The default strategy is the ProtectedDataCookieTransform and it uses DPAPI under the user scope (not machine scope). In this case DPAPI stores information in the user's profile, so in order to use it when you've impersonated another user you'll need to ensure that their entire profile is loaded.  You can do this by calling LoadUserProfile API to force the user's profile to be loaded.

    Another option would be to replace the ProtectedDataCookieTransform with the RSA-based cookie transform that uses an X509 certificate to encrypt the ClaimsPrincipal. In this case you would give access to the private key of the cert to the user you are impersonating. You can change the cookie transform by replacing the default SessionSecurityTokenHandler with another instance with different cookie transforms. The SSTH takes a list of cookietransforms in the ctor.


    Matias Woloski - http://blogs.southworks.net/mwoloski - southworks
    Saturday, May 9, 2009 10:12 PM
  • What the FAM is trying to do is to encrypt the ClaimsPrincipal with DPAPI to store it later in a cookie. The default strategy is the ProtectedDataCookieTransform and it uses DPAPI under the user scope (not machine scope). In this case DPAPI stores information in the user's profile, so in order to use it when you've impersonated another user you'll need to ensure that their entire profile is loaded.  You can do this by calling LoadUserProfile API to force the user's profile to be loaded.

    Another option would be to replace the ProtectedDataCookieTransform with the RSA-based cookie transform that uses an X509 certificate to encrypt the ClaimsPrincipal. In this case you would give access to the private key of the cert to the user you are impersonating. You can change the cookie transform by replacing the default SessionSecurityTokenHandler with another instance with different cookie transforms. The SSTH takes a list of cookietransforms in the ctor.


    Matias Woloski - http://blogs.southworks.net/mwoloski - southworks
    Under the LoadUserProfile solution, where in the ASP.NET life cycle (ASP.NET MVC in my case) should you invoke LoadUserProfile for the impersonated user?   When/where should you unload the profile for the impersonated user?


    Interesting that impersonation does not work with Geneva out of the box.    



    thanks
    • Marked as answer by scott_m Sunday, May 10, 2009 2:53 AM
    • Unmarked as answer by scott_m Sunday, May 10, 2009 2:53 AM
    Sunday, May 10, 2009 12:36 AM
  • Try login on to the machine using the account you are impersonating. That should create the profile for the first time. Alternatively you can do it with code with the API mentioned above, but I believe login the user will work.

    In any case in a production environment you don't want to use the ProtectedCookie transform because it won't work with web farms (profiles and master keys will be different in server 1 and server 2). 


    Matias Woloski - http://blogs.southworks.net/mwoloski - southworks
    • Marked as answer by scott_m Sunday, May 10, 2009 2:54 AM
    Sunday, May 10, 2009 1:36 AM
  • Hi, I've got the same problem... It seems that If I logon on the server with IISuser and I stay logged in, the webservice works. If I logout from IIS user and I recycle apppool of ws, I got the error again....

    Any other solution?

    Thank you!

     

    Tuesday, May 18, 2010 1:17 PM
  • Hi Matias,

    I'm experiencing this problem using WIF RTM under Windows 2003 Server (IIS6).  I'm using a domain service account as my app pool identity and can confirm that if I force the service account profile to load by running a command prompt as my service account then all is well.  Without the profile loaded I get "CryptographicException: The system cannot find the file specified".

    I'm interested in your suggestion to replace the ProtectedDataCookieTransform but I'm not sure how best to go about this.  Can this be achieved under the microsoft.identitymodel section in web.config?

    I was hoping there would be a way to force the framework to use the all users profile but if I can use a certificate instead then this would be just as good.

    Thanks, Ian.

    Tuesday, May 18, 2010 2:12 PM