2017-02-28 70 views
6

我有一個運行在.NET Framework 4.6.2下的WCF服務。我已經使用在web.config前與我的自定義IAuthorizationPolicy這樣配置服務:從IAuthorizationPolicy設置Thread.CurrentPrincipal?

<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> 

現在我需要對等維護做到這一點的代碼,這是什麼樣子:

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) 

在IAuthorizationPolicy我只是像以前這樣設置principla和它打破這裏:

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); 

的問題是日在我試圖運行時:

(UserContextOnService)Thread.CurrentPrincipal;

在服務方法中,我得到異常,CurrentPrincipal是WindowPrincipal

我可以通過使用此代碼得到正確的校長:

OperationContext.Current.ServiceSecurityContext.AuthorizationContext.Properties["Principal"] 

但是,這將意味着在許多地方需要修改,其內容具有獲取只需Thread.CurrentPrincipal中。

我懷疑我在配置中丟失了什麼東西?

編輯:試圖設置Thread.CurrentPrincipal = userContext;在Evaluate方法中,但這沒有幫助,Thread.CurrentPrincipal如果仍然是WindowsPrinciple?我懷疑servicemethod是以另一個線程結束,然後是執行Evaluate的線程。

回答

3

當開始服務這需要設置,以及:

serviceAuthorizationBehavior.ExternalAuthorizationPolicies = new ReadOnlyCollection<IAuthorizationPolicy>(new IAuthorizationPolicy[] { new CustomAuthorizationPolicy_ClientService() }); 

serviceAuthorizationBehavior.PrincipalPermissionMode = PrincipalPermissionMode.Custom; 
serviceAuthorizationBehavior.ServiceAuthorizationManager = new CustomServiceAuthorizationManager(); 

這是正確的上述下面的行進行