【问题标题】:Delivering a JWT SecurityToken to a WCF client将 JWT SecurityToken 传递给 WCF 客户端
【发布时间】:2013-05-01 04:52:43
【问题描述】:

我需要根据用户名/密码身份验证生成令牌并向客户端发出令牌。我尝试了几种方法来解决这个问题,但都遇到了问题。

我的第一个计划是在我的 WCF 端点上实现 WS-Trust 问题。我发现这样做的例子是:

[OperationContract(Action = "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue",
                   ReplyAction = "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue")]
Message IssueToken(Message rstMessage);

但是,4.5 中对 WIF 的更改以将其集成到适当的 .NET Framework 中,破坏了将 Message 转换为 RequestSecurityToken 的示例代码的其余部分。 WSTrustRequestSerializer 似乎可以做到这一点,但它需要 WSTrustSerializationContext,而且关于如何创建或配置此上下文对象的信息很少。

我尝试简单地将我想用于我的 SecurityToken 类型的 JWT 序列化为一个字符串并将其返回给客户端,但看起来将它反序列化为 WCF 可以使用的 SecurityToken 需要我发送 JWTSecurityToken 和 Handler在客户端,我想避免的事情。虽然 WS-Trust 绑定似乎以某种方式回避了这一点并生成了一个 GenericXmlSecurityToken,但我似乎无法找到如何自己创建其中一个。

关于如何在 WS-Trust 中序列化/反序列化 RequestSecurityToken 和 RequestSecurityTokenResponse 对象,或者如何在 WS-Trust 框架之外序列化/反序列化令牌有任何想法吗?还是其他想法?

【问题讨论】:

  • 为什么这么复杂 - 只需添加一个操作 GetToken(或其他东西)并返回一个字符串...
  • 问题是如何获取该字符串并将其转换为 SecurityToken 以传递给 CreateChannelWithIssuedToken,而无需将 JWT 令牌和处理程序与客户端一起发送。您是否建议我简单地将令牌字符串作为标头传递,然后使用行为来手动处理令牌?

标签: wcf wif


【解决方案1】:

我所做的是: 我创建了自己的响应消息版本,其中包含创建 GenericXmlSecurityToken 所需的位。这通常是从 WSTrustChannel 返回的,所以这似乎是正确的做法。值得庆幸的是,包装 JWT 的 GenericXmlSecurityToken 的大多数参数都是空的。我只需要序列化的令牌,用服务中 JWTSecurityTokenHandler 上的 WriteToken 序列化,以及 validFrom 和 validTo 值。

客户端代码:

XmlElement element = document.CreateElement("wsse", "BinarySecurityToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
element.SetAttribute("ValueType", "urn:ietf:params:oauth:token-type:jwt");
element.SetAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
UTF8Encoding encoding = new UTF8Encoding();
element.InnerText = Convert.ToBase64String(encoding.GetBytes(jwtToken));

GenericXmlSecurityToken token = new GenericXmlSecurityToken(
    element,
    null,
    validFrom,
    validTo,
    null,
    null,
    null);

var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.IssuedKeyType = SecurityKeyType.BearerKey;
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.IssuedTokenType = "urn:ietf:params:oauth:token-type:jwt";

var factory2 = new ChannelFactory<IService1>(binding, new EndpointAddress("https://localhost:44300/Service1.svc"));
factory2.Credentials.SupportInteractive = false;
factory2.Credentials.UseIdentityConfiguration = true;

var proxy = factory2.CreateChannelWithIssuedToken(token);

var info = proxy.DoWork();

web.config 的相关部分:

绑定:

<ws2007FederationHttpBinding>
  <binding>
    <security mode="TransportWithMessageCredential">
      <message issuedKeyType="BearerKey" establishSecurityContext="false" issuedTokenType="urn:ietf:params:oauth:token-type:jwt"/>
    </security>
  </binding>
</ws2007FederationHttpBinding>

identityModel 部分:

<system.identityModel>
  <identityConfiguration>
    <audienceUris>
      <add value="--audienceUri--"/>
    </audienceUris>
    <securityTokenHandlers>
      <add type="--namespace--.CustomJWTSecurityTokenHandler, --my dll--" />
      <securityTokenHandlerConfiguration>
        <certificateValidation certificateValidationMode="PeerTrust"/>
      </securityTokenHandlerConfiguration>
    </securityTokenHandlers>
    <issuerNameRegistry>
      <trustedIssuers>
        <add name="--issuer--"  thumbprint="--thumbprint--"/>
      </trustedIssuers>
    </issuerNameRegistry>
  </identityConfiguration>
</system.identityModel>

还有来自这个问题的 CustomJWTSecurityTokenHandler(我的场景只需要 validIssuer 部分):How to configure MIcrosoft JWT with symmetric key?

我还没有看到在其他地方使用的issuedTokenType 属性,但我发现它对于让我的代码正常工作至关重要。没有它,我收到此错误:“MessageSecurityException: 找不到 'Microsoft.IdentityModel.Tokens.JWT.JWTSecurityToken' 令牌类型的令牌身份验证器。根据当前的安全设置,无法接受该类型的令牌。”

作为一种解决方案,这可能有点矫枉过正,但我​​认为它最大限度地减少了自定义代码的数量,并将其集中在我觉得更舒服的地方。

感谢 user2338856 和 leastprivilege 让我成功!

【讨论】:

  • 正在搜索最后的调整,您提供了!
  • 嘿妮可。我知道已经有一段时间了,但我正在努力实现同样的目标,但似乎无法让它发挥作用。我正在使用System.IdentityModel.Tokens.Jwt NuGet 包中的JwtSecurityTokenHandler 的RTM 版本。令牌被识别,但我最终得到与this post 完全相同的错误。你有什么线索吗?
【解决方案2】:

AFAIK,为此您需要一个 WSFederationBinding。开箱即用,这只支持 Saml 令牌。要让它支持 Jwt 令牌,您需要添加一个能够在 WiF 管道中处理它的 securitytokenhandler。不幸的是,来自 Microsoft 的实验处理程序对配置文件不友好,因此您需要对其进行子类化以允许您在 config.xml 中指定属性。或者,您可以使用 ThinkTecture Jwt 处理程序,该处理程序在配置中也不是很容易设置。 设置所有这些将花费您相当长的时间,我不知道网络上有任何这样做的示例。

【讨论】:

    猜你喜欢
    • 2011-07-01
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-15
    相关资源
    最近更新 更多