2012-03-10 10 views
5

Cercare un piccolo consiglio (o forse anche una risposta diretta).Passare HttpContext.Current.User.Identity a WCF

Ho un sito Web MVC3. Ho anche un set di servizi WCF in esecuzione (per ora tutto è nella stessa scatola).

Che cosa sono provare tentare di autenticare il client (quella parte funziona correttamente), quindi passare tale utente autenticato su varie chiamate WCF.

Al momento ho collegato il metodo Application_AuthenticateRequest() in Global.Asax, che si riduce alla creazione di una nuova GenericIdentity & GenericPrincipal, assegnando tale entità a HttpContext.Current.User:

... 
GenericIdentity identity = new GenericIdentity(userName); 
GenericPrincipal principal = new GenericPrincipal(identity, null); 
HttpContext.Current.User = principal; 
... 

E quella parte sembra funzionare bene come bene.

Ma quando ho raggiunto il mio servizio, ho completamente perso l'utente che ho impostato. I valori sono vuoti o falsi.

L'unica cosa principale che ho notato è che sul lato client, l'oggetto HttpContext.Current.User.Identity è di tipo {System.Web.Security.FormsIdentity}, ma nel servizio è di tipo {System.Security.Principal.WindowsIdentity}.

Basandomi su alcune delle cose che ho letto, sembra che modificare semplicemente il mio in modo che contenga aspNetCompatibilityEnabled="true" potrebbe essere sufficiente per farlo funzionare correttamente. Ma non è quello che sto vedendo. Quindi o non sto capendo tutto (una possibilità molto buona) o ho qualcosa di rovinato (un'altra buona possibilità).

Quindi la mia domanda. E 'anche possibile, e se è così - pensieri su quello che mi manca? Ho notato che alcuni altri hanno pubblicato qualcosa di simile ma non hanno mai ricevuto una risposta definitiva (vedi here e here).

Qualsiasi suggerimento è molto apprezzato.

+0

È strano che dite di vedere 'FormsIdentity' quando specificate specificamente' GenericIdentity' nel contesto utente corrente. Ti sei mixato? –

risposta

2

Non riesco a rispondere direttamente alla tua domanda, ma spero ti possa aiutare a trovare la risposta definitiva.

Hai 2 livelli di servizio e sembra che il tuo requisito sia quello di condividere l'identità di autenticazione tra tutti i livelli.

Quindi, in linea di principio, è necessario (almeno) gli stessi meccanismi di autenticazione o algoritmi o tecniche per raggiungere questo obiettivo. Ma a questo punto non stai usando lo stesso (e hai notato quando hai visto uno FormsIdentity e uno WindowsIdentity lì).

Fatti:

  • Sarà necessario lo stesso meccanismo di autenticazione.
  • Qualunque sia il meccanismo che si utilizza, è necessario supportare il terzo hop che si desidera effettuare (ovvero è possibile utilizzare l'identità di un utente con un terzo servizio senza effettivamente disporre delle credenziali per eseguire nuovamente l'autenticazione).

Problemi:

  • Se si continua a utilizzare l'autenticazione Forms, allora avrete bisogno di nuovamente con il vostro servizio WCF (e, naturalmente, fornire le credenziali di identità, thismaggio aiuto).Questo lo trovo difficile a meno che tu non mantenga la password che l'Utente usava per autenticarsi che generalmente è una cattiva idea.
  • Se si continua a utilizzare l'autenticazione di Windows per il sito, si verificherà un problema se l'utente effettua l'accesso da Intranet. La cosa divertente con Kerberos (Active Directory utilizza Kerberos) è che consente all'utente di accedere alle risorse remote senza eseguire di nuovo l'autenticazione ... ma questo token di identità utente è valido solo per 1 hop. Mentre i servizi WCF e MVC si trovano sullo stesso server, funzionerà, ma se alla fine si estrae il servizio WCF ... si tratta di un terzo limite di casella ... un terzo salto e il ticket Kerberos non sarà sufficiente.

Quindi ... ignorando le vostre esigenze, vorrei per prima cosa suggerire:

  • Dimenticate l'autenticazione sul vostro strato WCF
  • Fai l'accesso servizio WCF privato (lavorare le vostre abilità di rete. .. firewall e altri). Comincerei facendo girare WCF su un sito Web IIS separato che non ascolta la porta 80 (o 443) e assicurati che Firewall blocchi l'accesso alla tua nuova porta WCF da IP al di fuori della tua LAN (o anche meglio, al di fuori del tuo bianco lista (localhost per ora)).
  • Specificare l'identità dell'utente come parametro di ogni chiamata WCF. Oppure, se ti senti selvaggio, esplora i modi per specificare un'identità utente attraverso le intestazioni SOAP (se il tuo WCF usa SOAP). Anche un'intestazione personalizzata dovrebbe andare bene. Ci si fiderà quindi del proprio sito Web per contestare e autenticare correttamente gli utenti prima di concedere loro l'accesso ai servizi WCF.

Ho visto questo correre molte volte ormai. Non avere l'autenticazione su un servizio privato è un buon accordo sulle prestazioni, ma è necessario prendere precauzioni, in generale, la maggior parte degli attacchi IT proviene dalla LAN interna.