将JWT SecurityToken传递给WCF客户端
我需要根据用户名/密码身份验证为客户端生成令牌并向其发放令牌。我尝试了几种方法来解决这个问题,但是他们都遇到了问题。将JWT SecurityToken传递给WCF客户端
我的第一个计划是在我的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中适当打破了样本代码的其余部分消息转换为RequestSecurityToken。 WSTrustRequestSerializer似乎这样做,但它需要WSTrustSerializationContext,并且关于如何创建或配置此上下文对象的信息很少。
我试着简单地将我想用于我的SecurityToken类型的JWT序列化为一个字符串并将其返回给客户端,但它看起来像将其反序列化为WCF可以使用的SecurityToken将需要我发送JWTSecurityToken和处理器在客户端,我想避免的东西。尽管WS-Trust绑定似乎以某种方式回避了这种情况,并生成了GenericXmlSecurityToken,但我似乎无法找到如何自己创建其中的一个。
有关如何序列化/反序列化WS-Trust中的RequestSecurityToken和RequestSecurityTokenResponse对象,或者如何序列化/反序列化WS-Trust框架之外的令牌的任何想法?还是其他想法?
我所做的是: 我创建了自己的响应消息版本,其中包含创建GenericXmlSecurityToken所需的位。这通常是从WSTrustChannel返回的,所以它看起来是正确的。谢天谢地,包装JWT的GenericXmlSecurityToken的大部分参数都是空的;我只需要序列化令牌,使用服务中的JWTSecurityTokenHandler上的WriteToken和validFrom和validTo值序列化。
客户机代码:在web.config的
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();
相关位:
的结合:
<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>
而CustomJWTSe curityTokenHandler从这个问题(只有validIssuer部分是需要为我的方案):How to configure MIcrosoft JWT with symmetric key?
我还没有看到其他地方使用issuedTokenType属性,但我发现这是至关重要的让我的代码工作。没有它,我得到这个错误:“MessageSecurityException:无法找到'Microsoft.IdentityModel.Tokens.JWT.JWTSecurityToken'令牌类型的令牌认证程序。该类型的令牌不能根据当前的安全设置被接受。”
这可能是矫枉过正的解决方案,但我认为它最小化的自定义代码的数量和集中它的地方,我感觉更舒服。
由于双方user2338856和leastprivilege你为我中途有
正在搜索最后的调整,你提供了他们! – Max 2014-04-19 18:09:17
嘿妮可。我发誓已经有一段时间了,但我试图达到同样的目的,似乎无法让它工作。我正在使用'System.IdentityModel.Tokens.Jwt' NuGet包中的'JwtSecurityTokenHandler'的RTM版本。令牌被识别,但是我最终得到的错误与[本帖]完全相同(http://stackoverflow.com/questions/27425866/sending-jwt-token-to-wif-wcf-service)。你有没有任何线索? – 2015-05-20 08:48:59
AFAIK,你需要一个WSFederationBinding。开箱即用,这只支持Saml令牌。为了让它支持Jwt令牌,你需要添加一个能够在WiF管道中处理它的securitytokenhandler。不幸的是,来自Microsoft的实验性处理程序不是那种配置文件友好的,因此您需要对它进行子类化以允许您在config中指定属性。或者,您可以使用ThinkTecture Jwt处理程序,这在配置中也不是很容易设置。 设置所有这一切将需要相当长的一段时间,我不知道在网络上的任何这样做的例子。
为什么这么复杂 - 简单地添加一个操作为gettoken(或东西),并返回一个字符串... – leastprivilege 2013-05-01 07:11:36
的问题是如何把这个字符串,并把它变成一个SecurityToken传递给CreateChannelWithIssuedToken,而无需将JWT令牌和处理程序与客户端一起传送。您是否建议仅传递令牌字符串作为标题,然后使用行为来手动处理令牌? – 2013-05-01 18:25:22