【问题标题】:Set the Thread.CurrentPrincipal from IAuthorizationPolicy?从 IAuthorizationPolicy 设置 Thread.CurrentPrincipal?
【发布时间】:2017-02-28 15:06:02
【问题描述】:

我有一个在 .NET Framework 4.6.2 下运行的 WCF 服务。我之前使用过 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>

现在我需要在代码中执行此操作,这就是它的样子:

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 中,我像以前一样设置了这样的原则,但它确实在这里中断:

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 的线程。

【问题讨论】:

    标签: c# wcf principal


    【解决方案1】:

    启动服务时也需要设置:

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

    这是在以下行的正上方完成的:

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

    【讨论】:

    • 在CustomServiceAuthorizationManager中需要实现什么?
    猜你喜欢
    • 1970-01-01
    • 2013-05-09
    • 2015-09-29
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    • 2015-12-24
    • 2017-01-02
    • 1970-01-01
    相关资源
    最近更新 更多