将 JWT SecurityToken 传递给 WCF 客户端 [英] Delivering a JWT SecurityToken to a WCF client

查看:25
本文介绍了将 JWT SecurityToken 传递给 WCF 客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need to generate and issue a token to clients based on username/password authentication. I've tried several approaches to solving this problem, but all of them have run into issues.

我的第一个计划是在我的 WCF 端点上实施 WS-Trust Issue.我发现这样做的例子使用了:

My first plan was to implement WS-Trust Issue on my WCF endpoint. The example I found which did this used:

[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 似乎可以做到这一点,但它需要 WTrustSerializationContext,关于如何创建或配置此上下文对象的信息很少.

However, the changes to WIF in 4.5 to integrate it into the .NET Framework proper have broken the rest of the sample code to convert Message into RequestSecurityToken. WSTrustRequestSerializer seems to do this, but it requires WSTrustSerializationContext, and there's little information on how to create or configure this context object.

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

I tried simply serializing out the JWT I want to use for my SecurityToken type into a string and returning it to the client, but it looks like deserializing it into a SecurityToken which WCF can use would require me to ship the JWTSecurityToken and Handler on the client, something I want to avoid. While the WS-Trust bindings seem to sidestep this somehow and produce a GenericXmlSecurityToken, I can't seem to find how to create one of these myself.

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

Any thoughts on either how to serialize/deserialize the RequestSecurityToken and RequestSecurityTokenResponse objects within WS-Trust, or how to serialize/deserialize the token outside of the WS-Trust framework? Or other ideas?

推荐答案

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

What I did was this: I created my own version of a response message which had the bits I needed to create a GenericXmlSecurityToken. This is what's generally returned from a WSTrustChannel, so it seemed like the right thing to do. Thankfully, most of the parameters for a GenericXmlSecurityToken wrapping a JWT are null; I only needed the serialized token, serialized with WriteToken on the JWTSecurityTokenHandler in the service, and the validFrom and validTo values.

客户端代码:

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 的相关部分:

Relevant bits of the web.config:

绑定:

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

identityModel 部分:

The identityModel section:

<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 部分):如何使用对称密钥配置 MIcrosoft JWT?

And the CustomJWTSecurityTokenHandler from this question (only the validIssuer part was required for my scenario): How to configure MIcrosoft JWT with symmetric key?

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

I haven't seen the issuedTokenType attribute used elsewhere, but I found it was essential to getting my code to work. Without it, I got this error: "MessageSecurityException: Cannot find a token authenticator for the 'Microsoft.IdentityModel.Tokens.JWT.JWTSecurityToken' token type. Tokens of that type cannot be accepted according to current security settings."

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

This might be overkill as a solution, but I think it minimizes the amount of custom code and centralizes it in places I feel more comfortable with.

感谢 user2338856 和 leastprivilege 让我走到了那里!

Thanks to both user2338856 and leastprivilege for getting me partway there!

这篇关于将 JWT SecurityToken 传递给 WCF 客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆