Wcf 我如何在服务端指定索赔类型要求,以便客户请求遵守这些要求?

Wcf 我如何在服务端指定索赔类型要求,以便客户请求遵守这些要求?,wcf,wif,claims-based-identity,Wcf,Wif,Claims Based Identity,我有: 也是身份提供者的被动STS“登录应用程序” 可以接受和处理ActAs令牌的活动STS WCF服务 网站依赖方 网站调用的WCF服务依赖方 所有这些都是使用Windows身份基础和自定义STS代码组合在一起的。不涉及Active Directory(ADFS) 我现在的工作是: 用户尝试访问网站RP 用户被重定向到被动STS 用户登录,获得颁发的令牌,重定向回web站点 Web站点RP向WCF RP发出服务调用,并传递ActAs令牌,以便进行委派 活动STS看到ActAs令牌进入并正确

我有:

  • 也是身份提供者的被动STS“登录应用程序”
  • 可以接受和处理ActAs令牌的活动STS WCF服务
  • 网站依赖方
  • 网站调用的WCF服务依赖方
所有这些都是使用Windows身份基础和自定义STS代码组合在一起的。不涉及Active Directory(ADFS)

我现在的工作是:

  • 用户尝试访问网站RP
  • 用户被重定向到被动STS
  • 用户登录,获得颁发的令牌,重定向回web站点
  • Web站点RP向WCF RP发出服务调用,并传递ActAs令牌,以便进行委派
  • 活动STS看到ActAs令牌进入并正确设置输出标识,因此主标识是ActAs令牌,调用方的标识被添加到参与者链中
  • WCF RP在一切就绪的情况下获得适当的令牌,当前线程主体具有正确的标识和声明
  • 我希望WCF RP向活动STS请求额外索赔。

    也就是说,在进入活动STS的RST中,我希望它包括服务所需的声明列表,以便在这些声明还不存在时可以获取这些额外的声明

    我已经通过修改web站点RP客户端上的绑定找到了实现此目的的方法,但我希望在WCF RP服务端上指定要求。

    我有一种感觉,它与我正在使用的绑定有关。我很难让ws2007FederationHttpBinding使用ActAs令牌,WIF身份培训工具包中的所有示例都使用customBinding,所以我也这样做了,它最终成功了。以下是WCF RP中的配置代码段,显示了我的绑定配置:

    <system.serviceModel>
      <bindings>
        <customBinding>
          <binding name="CustomBinding_FederatedService">
            <security
              authenticationMode="IssuedTokenForCertificate"
              messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10">
              <issuedTokenParameters tokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
                <issuer address="http://localhost:38901/ActiveSts.svc/IWSTrust13" />
                <issuerMetadata address="http://localhost:38901/ActiveSts.svc/mex" />
              </issuedTokenParameters>
            </security>
            <textMessageEncoding>
              <readerQuotas maxArrayLength="32767" />
            </textMessageEncoding>
            <httpTransport />
          </binding>
        </customBinding>
      </bindings>
    </system.serviceModel>
    
    
    
    如果我在调用web站点上更改配置以在issuedTokenParameters部分指示claimTypeRequirements,那么活动STS实际上会在RST中看到所需声明的列表。。。但这是在呼叫网站上,这对我来说是个问题

    如何使WCF RP能够指定其需要的其他声明,而无需在呼叫网站上复制该配置?


    如果这确实是一个绑定问题,那么如果您能向我展示上面给出的等效配置,这会有所帮助。我可以用适当的更改来更新网站和WCF服务,但我同样需要服务(或服务上的行为,或服务上的配置)来控制它所需的声明列表。服务不应接受缺少必需索赔的请求。

    事实证明,您必须这样做,即

  • 找出在客户端检索索赔要求的方法。这可能是某种中央配置服务、WS-Policy/元数据交换,或者您喜欢的任何东西
  • 手动为STS创建令牌请求。不要使用Microsoft.IdentityModel
    CreateChannelActingGas(令牌)
    扩展方法,而是使用
    WSTrustChannelFactory
    手动请求ActAs令牌(或新令牌)
  • 将手动请求的令牌添加到传出通道参数
  • 请注意,这并不能完全消除客户了解索赔要求列表的需要,但它确实让您能够以某种方式集中配置,甚至使用服务本身来提供索赔要求列表。不幸的是,Microsoft.IdentityModel堆栈中没有任何东西可以为您完成所有这一切。客户机绝对需要知道索赔要求列表,因为安全令牌请求是作为客户机通信的一部分发出的,而不是在服务操作请求传入时由服务发出的

    无论如何,您可以看到一些关于
    WSTrustChannelFactory
    WSTrustChannel
    的合理解释。我的解决方案就是基于此

    简而言之,没有所有的错误处理等,代码基本上如下所示:

    // You need the channel factory so you can get info about the endpoint.
    var factory = new ChannelFactory<IService>();
    
    // Get the issuedTokenParameters information from the binding.
    // You see this in the XML config but it's painful to access.
    var tokenParameters = factory.Endpoint.Binding
        .CreateBindingElements()
        .OfType<SecurityBindingElement>().First()
        .EndpointSupportingTokenParameters
        .Endorsing.OfType<IssuedSecurityTokenParameters>().First();
    
    // Prepare the RST.
    var trustChannelFactory = new WSTrustChannelFactory(tokenParameters.IssuerBinding, tokenParameters.IssuerAddress);
    var trustChannel = (WSTrustChannel)trustChannelFactory.CreateChannel();
    var rst = new RequestSecurityToken(RequestTypes.Issue);
    rst.AppliesTo = factory.Endpoint.Address;
    
    // If you're doing delegation, set the ActAs value.
    var principal = Thread.CurrentPrincipal as IClaimsPrincipal;
    var bootstrapToken = principal.Identities[0].BootstrapToken;
    rst.ActAs = new SecurityTokenElement(bootstrapToken);
    
    // Here's where you can look up claims requirements dynamically.
    rst.Claims.Add(new RequestClaim("http://dynamically-added-claim"));
    
    // Get the token and attach it to the channel before making a request.
    RequestSecurityTokenResponse rstr = null;
    var issuedToken = trustChannel.Issue(rst, out rstr);
    var fccParameters = new FederatedClientCredentialsParameters();
    fccParameters.IssuedSecurityToken = issuedToken;
    var channel = factory.CreateChannel();
    ((IChannel)channel).GetProperty<ChannelParameterCollection>().Add(fccParameters);
    
    // NOW you can make the request.
    channel.DoWork();
    
    //您需要通道工厂,以便获取有关端点的信息。
    var factory=新的ChannelFactory();
    //从绑定中获取issuedTokenParameters信息。
    //您可以在XML配置中看到这一点,但是访问它很痛苦。
    var tokenParameters=factory.Endpoint.Binding
    .CreateBindingElements()
    .OfType().First()
    .EndpointSupportingTokenParameters
    .背书.of type().First();
    //准备RST。
    var trustChannelFactory=new WSTrustChannelFactory(tokenParameters.IssuerBinding,tokenParameters.issueAddress);
    var trustChannel=(WSTrustChannel)trustChannelFactory.CreateChannel();
    var rst=新的RequestSecurityToken(RequestTypes.Issue);
    rst.AppliesTo=factory.Endpoint.Address;
    //如果要执行委派,请设置ActAs值。
    var principal=Thread.CurrentPrincipal作为IClaimsPrincipal;
    var bootstrapToken=主体。标识[0]。bootstrapToken;
    rst.ActAs=新的SecurityTokenElement(bootstrapToken);
    //在这里,您可以动态查找索赔要求。
    rst.Claims.Add(新的RequestClaim(“http://dynamically-added-claim"));
    //在发出请求之前,获取令牌并将其附加到通道。
    RequestSecurityTokenResponse rstr=null;
    var issuedToken=信任渠道。问题(rst,out rstr);
    var fccParameters=新的FederatedClientCredentialsParameters();
    fccParameters.IssuedSecurityToken=issuedToken;
    var channel=factory.CreateChannel();
    ((IChannel)channel.GetProperty().Add(fccParameters);
    //现在你可以提出请求了。
    道工();
    
    如果您希望优化某些通信流,这还允许您缓存已发布的令牌