2012-10-15 12 views
7

Ho letto nei forum MSDN, nel blog di Dominic Baier e in altre fonti che DPAPI non funzionerà immediatamente in Azure e che un approccio alla gestione dell'autenticazione federata in qualsiasi tipo di scenario Web farm è la sostituzione del DPAPI trasforma con uno che utilizza una chiave privata disponibile in tutta la farm, come la crittografia RSA che utilizza un certificato X509. Ho preso questo approccio nella mia domanda Azure MVC e configurato il SessionSecurityTokenHandler in questo modo:SessionSecurityTokenHandler che tenta di decodificare SessionSecurityToken in cookie crittografato con RSA utilizzando DPAPI; perché?

FederatedAuthentication.ServiceConfigurationCreated += (sender, args) => 
    { 
     var sessionTransforms = new List<CookieTransform>(new CookieTransform[] 
      { 
       new DeflateCookieTransform(), 
       new RsaEncryptionCookieTransform(args.ServiceConfiguration.ServiceCertificate), 
       new RsaSignatureCookieTransform(args.ServiceConfiguration.ServiceCertificate) 
      }); 
     var sessionHandler = new SessionSecurityTokenHandler(sessionTransforms.AsReadOnly()); 
     args.ServiceConfiguration.SecurityTokenHandlers.AddOrReplace(sessionHandler);      
    }; 

Utilizzando questa configurazione, siamo in grado di ricevere i token da un provider di identità e di emettere i cookie sicuri crittografati utilizzando queste trasformazioni. Funzionando nell'emulatore di Azure, tutto funziona come previsto. Tuttavia, nell'ambiente Azure, abbiamo intermittenza vediamo il seguente errore nel browser:

Key not valid for use in specified state. 

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Security.Cryptography.CryptographicException: Key not valid for use in specified state. 


Source Error: 

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. 

Stack Trace: 


[CryptographicException: Key not valid for use in specified state. 
] 
    System.Security.Cryptography.ProtectedData.Unprotect(Byte[] encryptedData, Byte[] optionalEntropy, DataProtectionScope scope) +577 
    Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded) +80 

[InvalidOperationException: ID1073: A CryptographicException occurred when attempting to decrypt the cookie using the ProtectedData API (see inner exception for details). If you are using IIS 7.5, this could be due to the loadUserProfile setting on the Application Pool being set to false. ] 
    Microsoft.IdentityModel.Web.ProtectedDataCookieTransform.Decode(Byte[] encoded) +433 
    Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ApplyTransforms(Byte[] cookie, Boolean outbound) +189 
    Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(XmlReader reader, SecurityTokenResolver tokenResolver) +862 
    Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler.ReadToken(Byte[] token, SecurityTokenResolver tokenResolver) +109 
    Microsoft.IdentityModel.Web.SessionAuthenticationModule.ReadSessionTokenFromCookie(Byte[] sessionCookie) +356 
    Microsoft.IdentityModel.Web.SessionAuthenticationModule.TryReadSessionTokenFromCookie(SessionSecurityToken& sessionToken) +123 
    Microsoft.IdentityModel.Web.SessionAuthenticationModule.OnAuthenticateRequest(Object sender, EventArgs eventArgs) +61 
    System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +80 
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +270 

Questo sembra suggerire che il SessionSecurityTokenHandler sta cercando di decifrare il cookie utilizzando DPAPI, ma perché? Non l'ho configurato per usare RSA sopra?

risposta

5

Bene, dopo molte ricerche, ho capito qual era il mio problema. Prima di impostare il ServiceConfigurationCreated, stavo facendo qualche configurazione che ha causato un accesso a FederatedAuthentication.ServiceConfiguration. According to MSDN, "L'evento ServiceConfigurationCreated viene generato quando il primo modulo HTTP nell'applicazione Web fa riferimento a ServiceConfiguration". Ho spostato la configurazione del gestore eventi nella parte superiore di Application_Start e tutto ha funzionato come dovrebbe, il che significa che l'evento, che si attiva solo una volta, è stato attivato prima che il gestore eventi venisse impostato.

Speriamo che questo salvi qualcuno per le 4+ ore che ho impiegato per eseguire questa operazione.

+0

Wow! Buona pesca! hai tutto il merito! – astaykov

+0

Bello !!! Ma perché non l'hai fatto attraverso il file di configurazione? http://blogs.msdn.com/b/distributedservices/archive/2012/10/29/wif-1-0-id1073-a-cryptographicexception-occurred-when-attempting-to-decrypt-the-cookie-using- the-protecteddata-api.aspx – antwoord

+0

@antwoord che sarebbe il modo più logico per configurarlo. Penso che il motivo per cui è stato eseguito nel gestore di 'Application_Start' era perché la persona che lo ha fatto non si rendeva conto che poteva essere fatto in' web.config', e non era un problema che volevo cambiare (sebbene dopo tutto potrebbe aver richiesto meno tempo). –

13

Si noti che ora è possibile utilizzare lo MachineKeySessionSecurityTokenHandler per firmare e crittografare i token di sessione nelle web farm.

Per utilizzare questo, è necessario rimuovere il default SessionSecurityTokenHandler e aggiungere il MachineKeySessionSecurityTokenHandler in Web.config:

<system.identityModel> 
    <identityConfiguration> 
    <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> 
    </identityConfiguration> 
</system.identityModel> 

L'MachineKeySessionSecurityTokenHandler fa uso della chiave macchina configurata in Web.config quindi sarà necessario aggiungere anche questo:

<system.web> 
    <machineKey validationKey="..." decryptionKey="..." validation="SHA1" decryption="AES" /> 
</system.web> 

Vedere questa domanda BrainThud

+0

Buon consiglio. Non sono sicuro che questo acquisti davvero qualcosa rispetto all'approccio RSA, ma sono contento di sapere che è disponibile. –

+1

Salvato la nostra vita. Grazie uomo. – SmartK8

+0

La mia chiave computer era già configurata, quindi questa è una soluzione solida. –