I have a WCF service running under the .NET Framework 4.6.2. I used to use web.config to configure the service using my custom IAuthorizationPolicy as follows:
<services> behaviorConfiguration="MyClientService.CustomValidator_Behavior" name="My.Service.Implementation.Services.MyClientService"> <endpoint binding="netHttpBinding" behaviorConfiguration="protoEndpointBehavior" address="BinaryHttpProto" bindingNamespace="http://My.ServiceContracts/2007/11" contract="My.ServiceContracts.IMyClientService" /> <endpoint binding="netHttpsBinding" behaviorConfiguration="protoEndpointBehavior" address="BinaryHttpsProto" bindingNamespace="http://My.ServiceContracts/2007/11" contract="My.ServiceContracts.IMyClientService" /> bindingConfiguration="netTcpCertificate" behaviorConfiguration="protoEndpointBehavior" bindingNamespace="http://My.ServiceContracts/2007/11" contract="My.ServiceContracts.IMyClientService" address="Sll"/> <host> </host> </service> </services> <behavior name="MyClientService.CustomValidator_Behavior"> <dataContractSerializer maxItemsInObjectGraph="2147483647" /> <serviceDebug includeExceptionDetailInFaults="true" /> <serviceMetadata httpGetEnabled="true" /> <customBehaviorExtension_ClientService /> <serviceThrottling maxConcurrentCalls="2000" maxConcurrentSessions="2147483647" maxConcurrentInstances="2000" /> <serviceCredentials> <clientCertificate> <authentication certificateValidationMode="PeerOrChainTrust" /> </clientCertificate> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="My.Service.Implementation.Security.CustomUsernamePasswordValidator, My.Service.Implementation" /> </serviceCredentials> <serviceAuthorization principalPermissionMode="Custom" serviceAuthorizationManagerType="My.Service.Implementation.Security.CustomServiceAuthorizationManager, My.Service.Implementation"> <authorizationPolicies> <add policyType="My.Service.Implementation.Security.CustomAuthorizationPolicy_ClientService, My.Service.Implementation" /> </authorizationPolicies> </serviceAuthorization> </behavior>
Now I need to do swtich in the code, and here is what it looks like:
var endpoint = new System.ServiceModel.Description.ServiceEndpoint(System.ServiceModel.Description.ContractDescription.GetContract(typeof(IMyClientService)), binding, new EndpointAddress(endPointAddress)); endpoint.EndpointBehaviors.Add(new ProtoBuf.ServiceModel.ProtoEndpointBehavior()); serviceHost.AddServiceEndpoint(endpoint); ServiceAuthorizationBehavior serviceAuthorizationBehavior = serviceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>(); if (serviceAuthorizationBehavior == null) { serviceAuthorizationBehavior = new ServiceAuthorizationBehavior(); serviceHost.Description.Behaviors.Add(serviceAuthorizationBehavior); } serviceAuthorizationBehavior.ExternalAuthorizationPolicies = new ReadOnlyCollection<IAuthorizationPolicy>(new IAuthorizationPolicy[] { new CustomAuthorizationPolicy_ClientService() }); ((ServiceBehaviorAttribute)serviceHost.Description.Behaviors[typeof(ServiceBehaviorAttribute)]).MaxItemsInObjectGraph = 2147483647; ((ServiceBehaviorAttribute)serviceHost.Description.Behaviors[typeof(ServiceBehaviorAttribute)]).IncludeExceptionDetailInFaults = true; ServiceThrottlingBehavior throttleBehavior = new ServiceThrottlingBehavior { MaxConcurrentCalls = 200, MaxConcurrentInstances = 2147483647, MaxConcurrentSessions = 2000, }; serviceHost.Description.Behaviors.Add(throttleBehavior); Console.WriteLine("Starting service..."); serviceHost.Open(); Console.WriteLine("Service started successfully (" + uri + ")"); return serviceHost; } catch(Exception ex)
In IAuthorizationPolicy, I install Principla the same as before, and here it breaks down:
var userContext = new UserContextOnService(new ClientIdentity { AuthenticationType = "regular", IsAuthenticated = true, Name = "username" }, currentAnvandare, LoginType.UsernamePassword); userContext.OrbitToken = orbitToken; evaluationContext.Properties["Principal"] = userContext; SharedContext.Instance.AddUserContext(person.PersonId.ToString(), userContext);
The problem is that when I try to run this:
(UserContextOnService) Thread.CurrentPrincipal;
In the service method, I get an exception, CurrentPrincipal is WindowPrincipal ?
I can get the correct Principal using this code:
OperationContext.Current.ServiceSecurityContext.AuthorizationContext.Properties["Principal"]
But that would mean changing in MANY places where context is retrieved only with Thread.CurrentPrincipal.
I suspect something is missing in the configuration?
Edit: tried to set Thread.CurrentPrincipal = userContext; in the Evaluate method, but that doesn’t help, Thread.CurrentPrincipal, if still WindowsPrinciple? I suspect that the servicemethod ends in another thread, then the one that runs Evaluate.