2011-03-02 20 views
6

Quando mi forniscono le credenziali al cliente con codice seguente:Come ottenere il nome utente e la password nella parte di servizio di una chiamata WCF?

myChannelFactory.Credentials.UserName.UserName = "username"; 
myChannelFactory.Credentials.UserName.Password = "password"; 

Poi sul lato server vedo che queste credenziali sono disponibili in

operationContext.IncomingMessageHeaders[1] 

Tuttavia Esiste un metodo più convenenient per ottenere il nome utente e la parola d'ordine? Tutto quello che vedo in OperationContext è caos di proprietà e liste non classificate e non riesco a trovare nulla che indichi dove posso ottenere questo.

+0

Perché lo vuoi? Stai cercando di eseguire un'autenticazione aggiuntiva? – McKay

risposta

3

È possibile utilizzare lo statico Current property su ServiceSecurityContext class per ottenere l'attuale ServiceSecurityContext per l'operazione che viene chiamata.

È possibile quindi utilizzare il PrimaryIdentity property al fine di ottenere l'identità dell'utente con le credenziali passate in.

Tuttavia, non lo farà (e non dovrebbe), esporre la password. Se hai veramente bisogno della password, dovrai scendere al livello del messaggio e ispezionare le intestazioni, come hai visto.

+0

No, questo è qualcos'altro. In SecurityCServiceContext contiene gli utenti WINDOWS CREDENZIALI. È qualcosa di totalmente diverso dalle credenziali che ho impostato sulla fabbrica di canali. –

+0

@ Kalaz: No, non è vero, la proprietà WindowsIdentity fornisce CREDENZIALI WINDOWS. PrimaryIdentity è qualcos'altro completamente. – casperOne

2

Questo dipende interamente dall'associazione che si sta utilizzando e non esiste una risposta generale.

Ad esempio, se si utilizza il NetNamedPipeBinding e fare

myChannelFactory.Credentials.UserName.UserName = "username"; 
myChannelFactory.Credentials.UserName.Password = "password"; 

si sta sprecando il vostro tempo: il lato client di associazione non farà nulla con questi dati, non sarà nel messaggio, e ha vinto essere accessibile a tutti dal lato del servizio

Il binding consumerà questi dati solo se è configurato con opzioni di sicurezza che specificano l'utilizzo di credenziali nome utente/password. Tutti i collegamenti standard che lo fanno utilizzeranno le credenziali per l'autenticazione, i cui risultati verranno quindi visualizzati nel servizio tramite lo ServiceSecurityContext come indicato da casperOne e non includeranno i dati della password.

Per supportare l'autenticazione, i dati devono essere trasportati da qualche parte nelle intestazioni dei messaggi. Esattamente dove e in che forma sarà di nuovo vincolante-dipendente. Non dare per scontato che li troverai sempre in operationContext.IncomingMessageHeaders[1].

MODIFICA: Potrebbe essere possibile creare un'associazione personalizzata che offre ciò che si sta cercando.

CustomBinding binding = new CustomBinding(...); 
binding.Elements.Insert(1, 
    SecurityBindingElement.CreateUserNameOverTransportBindingElement()); 

Sul lato servizio, fornire una UserNamePasswordValidator e configurare le credenziali in questo modo:

serviceHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = 
    System.ServiceModel.Security.UserNamePasswordValidationMode.Custom; 
servicehost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = 
    new MyUserNamePasswordValidator(); 

Il nome utente e la password saranno poi consegnati al metodo di MyUserNamePasswordValidatorValidate.

ATTENZIONE: questo non è un meccanismo di autenticazione sicuro a meno che non si utilizzi un trasporto sicuro, poiché le credenziali vengono inviate in chiaro nell'intestazione del messaggio.

+0

Hm sì vero. Posso configurare l'associazione personalizzata in modo da avere entrambe le informazioni sul lato server in un posto nel codice? (nome utente/password e informazioni sulle credenziali del dominio) Ho bisogno di entrambi i pezzi in un unico posto in modo da poter usare quello valido. –

+0

@ Kalaz: vedere la modifica alla mia risposta. È possibile eseguire la convalida del nome utente/password personalizzata. Ma non sono sicuro se questo è esattamente ciò che stai cercando, come ti riferisci anche alle credenziali di dominio. –

+0

Proverò il tuo suggerimento entro la fine della settimana. Per eliminare la confusione relativa alle credenziali di dominio: quello che sto cercando è un modo per autenticare l'utente tramite la sua appartenenza al dominio + il mio login/password personalizzati. In realtà userò l'appartenenza al dominio in modo che l'applicazione si comporti in modo univoco. Tuttavia, quando le informazioni sul dominio non sono disponibili, userò le credenziali personalizzate. Se la tua soluzione offre SecurityContext accessibile con informazioni sul dominio, sarà ciò che sto cercando. –

Problemi correlati