IDispatchMessageInspector和Thread.CurrentPrincipal

时间:2013-10-14 12:27:38

标签: wcf

我已经实现了一个自定义IDispatchMessageInspector,以便解析一个自定义标记类型。解析令牌后我分配:

ServiceSecurityContext.Current.AuthorizationContext.Properties["ClaimsPrincipal"] = claimsPrincipal;

ServiceSecurityContext.Current.AuthorizationContext.Properties["Identities"] = identities;
Thread.CurrentPrincipal = claimsPrincipal;

我认为在我的IDispatchMessageInspector中分配了ClaimsPrincipal后,它应该在我的服务方法中可用,不幸的是我在那里有一个WindowsPrincipal(IsAuthentificated = false)。

var currentIdentity = Thread.CurrentPrincipal as ClaimsPrincipal;

有什么想法吗?

修改 我的web.config:

<services>
      <service name="EchoService.TestEchoService">
        <endpoint address="api" bindingConfiguration="secured" binding="webHttpBinding" behaviorConfiguration="rest" contract="EchoService.IEchoService"/>
      </service>
    </services>
<behaviors>
      <serviceBehaviors>        
        <behavior>
          <serviceCredentials useIdentityConfiguration="true">                        
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>        
        <behavior name="rest">
          <webHttp helpEnabled="true" automaticFormatSelectionEnabled="true"/>        
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment>
      <serviceActivations>
        <add relativeAddress="echo.svc" factory="System.ServiceModel.Activation.ServiceHostFactory" service="EchoService.TestEchoService"/>
      </serviceActivations>
    </serviceHostingEnvironment>
  </system.serviceModel>
<system.identityModel>
  <identityConfiguration>
    <securityTokenHandlers>
      <clear/>
      <add type="EchoService.Host.Tokens.SimpleWebTokenHandler,EchoService.Host"></add>
    </securityTokenHandlers>    
  <audienceUris>
    <clear/>
    <add value="http://securitytestrealm/"/>
  </audienceUris>
          <issuerTokenResolver type="System.IdentityModel.Tokens.NamedKeyIssuerTokenResolver,System.IdentityModel.Tokens.Jwt">        
            <securityKey symmetricKey="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=" name="YYYYYYYYYYYYYYYYYYY" />
          </issuerTokenResolver>
  </identityConfiguration>

EDIT2:

通话顺序:

Contructor =&gt; GetTokenTypeIdentifiers =&gt; TokenType

在GetTokenTypeIdentifiers中,我返回:

return new string[] { "http://schemas.microsoft.com/2009/11/identitymodel/tokens/swt" };

如果我第一次打电话给我的服务,这个顺序就会发生。 有趣的是,在此之后调用时,没有调用任何Handlers方法。

3 个答案:

答案 0 :(得分:1)

不应在IDispatchMessageInspector中处理标记。

您需要实现SecurityTokenHandler,它将允许您读取令牌并提取它携带的任何内容=&gt;将其转换为声明集合,然后返回该集合。提供的索赔收集将自动用于通过WCF管道创建ClaimsPrincipal。

检查以下链接:

http://msdn.microsoft.com/en-us/library/system.identitymodel.tokens.securitytokenhandler.validatetoken.aspx

修改

您有两种可能的方法来向管道添加令牌处理程序。一种是实现自定义服务主机:

public class CustomServiceHost : ServiceHost
{
    protected override void OnOpening()
    {
        base.OnOpening();
        IdentityConfiguration identityConfiguration = new IdentityConfiguration();
        identityConfiguration.SecurityTokenHandlers.Clear();
        identityConfiguration.SecurityTokenHandlers.AddOrReplace(new CustomSecurityTokenHandler());
    }
}

或通过web.config中的相同xml段:

http://msdn.microsoft.com/en-us/library/hh568671.aspx

修改

        ServiceCredentials credentials = this.Description.Behaviors.Find<ServiceCredentials>();
        if (credentials == null)
        {
            credentials = new ServiceCredentials();
            this.Description.Behaviors.Add(credentials);
        }
        credentials.UseIdentityConfiguration = true;

答案 1 :(得分:0)

我能够解决这个问题。 唯一缺少的是web.config中的一个设置。

<serviceBehaviors>        
<behavior>
<serviceAuthorization principalPermissionMode="None" />

现在它按预期工作。有安全漏洞吗?

答案 2 :(得分:-1)

很抱歉,这不是WCF中的身份验证方式。您不能简单地从WCF处理管道中的某个位置分配Thread.CurrentPricipal,并假设WCF将自动拾取该事实证明用户已通过身份验证。

您需要挂钩到管道的正确位置。这将是serviceCredentials behavior