2013-05-01 120 views
1

我需要根據用戶名/密碼身份驗證爲客戶端生成令牌並向其發放令牌。我嘗試了幾種方法來解決這個問題,但是他們都遇到了問題。將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框架之外的令牌的任何想法?還是其他想法?

+0

爲什麼這麼複雜 - 簡單地添加一個操作爲gettoken(或東西),並返回一個字符串... – leastprivilege 2013-05-01 07:11:36

+0

的問題是如何把這個字符串,並把它變成一個SecurityToken傳遞給CreateChannelWithIssuedToken,而無需將JWT令牌和處理程序與客戶端一起傳送。您是否建議僅傳遞令牌字符串作爲標題,然後使用行爲來手動處理令牌? – 2013-05-01 18:25:22

回答

3

我所做的是: 我創建了自己的響應消息版本,其中包含創建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你爲我中途有

+0

正在搜索最後的調整,你提供了他們! – Max 2014-04-19 18:09:17

+0

嘿妮可。我發誓已經有一段時間了,但我試圖達到同樣的目的,似乎無法讓它工作。我正在使用'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

1

AFAIK,你需要一個WSFederationBinding。開箱即用,這隻支持Saml令牌。爲了讓它支持Jwt令牌,你需要添加一個能夠在WiF管道中處理它的securitytokenhandler。不幸的是,來自Microsoft的實驗性處理程序不是那種配置文件友好的,因此您需要對它進行子類化以允許您在config中指定屬性。或者,您可以使用ThinkTecture Jwt處理程序,這在配置中也不是很容易設置。 設置所有這一切將需要相當長的一段時間,我不知道在網絡上的任何這樣做的例子。

相關問題