简体   繁体   English

从IAuthorizationPolicy设置Thread.CurrentPrincipal?

[英]Set the Thread.CurrentPrincipal from IAuthorizationPolicy?

I have a WCF service running under .NET Framework 4.6.2. 我有一个在.NET Framework 4.6.2下运行的WCF服务。 I have used the web.config before to configure the service with my custom IAuthorizationPolicy like this : 我之前使用过web.config来使用我的自定义IAuthorizationPolicy配置服务,如下所示:

<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 swtich to do this in code and this is what that 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 the IAuthorizationPolicy i set the principla like this just as before and it does break here : 在IAuthorizationPolicy中,我像以前一样设置这样的原理,它在这里打破:

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; (UserContextOnService)Thread.CurrentPrincipal中;

In the service method I get exception, the CurrentPrincipal is a WindowPrincipal ? 在服务方法中我得到异常,CurrentPrincipal是一个WindowPrincipal

I can get the correct Principal by using this code : 我可以使用以下代码获得正确的Principal:

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

But that would mean to change in MANY places where the context is fetched with just Thread.CurrentPrincipal. 但这意味着要改变许多只使用Thread.CurrentPrincipal获取上下文的地方。

I suspect that I have lost something in the configuration? 我怀疑我在配置中丢失了一些东西?

Edit : Have tried to set the Thread.CurrentPrincipal = userContext; 编辑:尝试设置Thread.CurrentPrincipal = userContext; in the Evaluate method but this does not help, the Thread.CurrentPrincipal if still a WindowsPrinciple? 在Evaluate方法但这没有帮助,Thread.CurrentPrincipal如果仍然是WindowsPrinciple? I suspect that the servicemethod is ending up on another thread then the one that executes the Evaluate. 我怀疑servicemethod最终会在另一个线程上结束,然后是执行Evaluate的线程。

When starting the service this needed to be set as well : 启动服务时,还需要设置:

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

This is done right above the following line : 这是在以下行上方完成的:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 设置Thread.CurrentPrincipal异步? - Set Thread.CurrentPrincipal Asynchronously? 从Thread.CurrentPrincipal设置HttpContext.Current.User - Set HttpContext.Current.User from Thread.CurrentPrincipal 为什么我的IAuthorizationPolicy不使用我的CustomPrincipal设置Thread.CurrentPrincipal? - Why isn't my IAuthorizationPolicy setting the Thread.CurrentPrincipal with my CustomPrincipal? .Net Thread.CurrentPrincipal - .Net Thread.CurrentPrincipal Thread.CurrentPrincipal 是 ClaimsIdentity 返回 false 以及如何从 Thread.CurrentPrincipal 获取声明 - Thread.CurrentPrincipal is ClaimsIdentity returns false and how to get the claims from Thread.CurrentPrincipal 单元测试,如何设置Thread.CurrentPrincipal和IsAuthenticated - Unit Testing, how to set Thread.CurrentPrincipal and IsAuthenticated Windows Workflow和Thread.CurrentPrincipal - Windows Workflow and Thread.CurrentPrincipal 自定义SynchronizationContext在unittest中异步设置Thread.CurrentPrincipal - Custom SynchronizationContext to set Thread.CurrentPrincipal asynchronously in unittest 防止Thread.CurrentPrincipal跨应用程序域传播 - Preventing Thread.CurrentPrincipal from propagating across application domains 使用Thread.CurrentPrincipal与异步和等待? - Using Thread.CurrentPrincipal with async and await?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM