Thread.CurrentPrincipal del servizio di ASP.Net WCF viene gettato via da qualche intercettore in un ambiente federato (WIF)
-
20-09-2019 - |
Domanda
Ho un servizio WCF per chiamata che è ospitato in IIS (.svc). Nel costruttore della servizio, ho impostato Thread.CurrentPrincipal = HttpContext.Current.User come per questo articolo . In questo caso, HttpContext.Current.User è di tipo Microsoft.IdentityModel.Claims.ClaimsPrincipal e ha rivendicazioni che sono stati spediti dai miei STS passivi personalizzato.
Tuttavia, non appena faccio un passo nella mia operazione di servizio ed esaminare Thread.CurrentPrincipal , mentre questo oggetto è ancora di tipo Microsoft.IdentityModel.Claims.ClaimsIdentity , la oggetto stesso non è lo stesso di HttpContext.Current.User ( IsAuthenticated = false, AuthenticationType = "" e nome è nullo sulla Thread.CurrentPrincipal.Identity ), considerando che questi I valori sono tutti ancora compilati correttamente sul HttpContext.Current.User . Questo mi dice che qualcosa sta intercettando la chiamata al funzionamento e cambiando in modo non corretto la principale corrente a qualche generica, vuota, non autenticato reclami principale.
Ho controllato l'ID del thread nel costruttore e nel funzionamento ed è lo stesso in entrambi i luoghi, e la valutazione di Thread.CurrentPrincipal nella finestra immediata dopo l'assegnazione da HttpContext.Current .user mostra che l'identità filo viene impostato correttamente nel costruttore, quindi qualcosa è decisamente in esecuzione tra il costruttore e il metodo, e che qualcosa sta cambiando il mio Thread.CurrentPrincipal .
Qualcuno ha idea di che cosa sta facendo questo, e come posso fare per la prevenzione / risoluzione di questo comportamento?
Soluzione 2
Quando si configura un servizio per la federazione WIF, si chiama
FederatedServiceCredentials.ConfigureServiceHost(this);
Parte di ciò che questa chiamata non è quello di creare un custom ServiceAuthorizationManager di tipo IdentityModelServiceAuthorizationManager sul servizio di accoglienza. Questo manager autorizzazione sembra ottenere chiamato tra attivazione (costruzione) dell'istanza ed esecuzione dell'operazione, e sovrascrive Thread.CurrentPrincipal con un'istanza di IClaimsPrincipal , ma non sembra rendersi conto che è in esecuzione in modalità di compatibilità ASP.NET, in modo da non tirare il capitale da HttpContext.Current.User .
Sono stato in grado di aggirare questo comportamento derivante da IdentityModelServiceAuthorizationManager e l'override del CheckAccess metodo come segue:
public class CustomAuthorizationManager : IdentityModelServiceAuthorizationManager
{
public override bool CheckAccess(System.ServiceModel.OperationContext operationContext, ref System.ServiceModel.Channels.Message message)
{
var result = base.CheckAccess(operationContext, ref message);
var properties = operationContext.ServiceSecurityContext.AuthorizationContext.Properties;
properties["Principal"] = System.Web.HttpContext.Current.User;
return result;
}
}
Questo poi viene applicato per l'host del servizio nel seguente modo:
protected override void InitializeRuntime()
{
FederatedServiceCredentials.ConfigureServiceHost(this);
this.Authorization.ServiceAuthorizationManager = new CustomAuthorizationManager();
base.InitializeRuntime();
}
E ora, quando inserisco il mio funzionamento del servizio, ho la corretta IClaimsPrincipal su Thread.CurrentPrincipal , in modo dichiarativo PrincipalPermission ora funziona come previsto .
Altri suggerimenti
Ho appena incontrato un problema simile. Ho impostato il mio preside personalizzata nel costruttore del mio servizio WCF. Quando ho lasciato il costruttore, e il metodo entrato ho chiamato, il Thread.CurrentPrincipal stata sovrascritta da una vuota. Ho risolto questo aggiungendo il seguente comportamento:
<serviceAuthorization principalPermissionMode="None"></serviceAuthorization>
Questo ha funzionato bene per me.
impostazioni confgurazione per chiamata FederatedServiceCredentials.ConfigureServiceHost (questo );
è come sotto in system.serviceModel aggiungere seguente
<extensions>
<behaviorExtensions>
<add name="federatedServiceHostConfiguration" type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtensionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</behaviorExtensions>
</extensions>
sotto all'interno aggiungere folowing riga
<behavior name="serviceBehavior">
<federatedServiceHostConfiguration name="MyService" />
La mia ipotesi è che nulla sta intercettando la chiamata. O il CurrentPrincipal viene azzerato con il tempo si sta esaminando o sei in un thread diverso.
Controllare il CurrentPrincipal subito dopo l'assegnazione ad esso e si dovrebbe vedere il valore corretto.