2012-12-13 126 views
1

WCF的新手,但对过去的WSE *范例非常熟悉。我发现WCF的可配置性(阅读:复杂性)是相当大的挑战。如何处理saml:在WCF中声明?

我正在尝试使用.NET 4.0 WCF客户端来使用我们的政府提供的Web服务,该服务在WebSphere Application Server/6.1上运行。

他们的方案使用UsernameToken进行身份验证,并通过HTTPS传输加密交换SAML声明。这个SAML Assertion用于其他服务的操作。

当试图“登录”(即获得SAML断言),我收到来自WCF以下异常,当它试图处理返回SOAP:

“找不到令牌认证为' System.IdentityModel.Tokens.SamlSecurityToken'令牌类型,根据当前的安全设置,该类型的令牌不能被接受。“

这里是我的设置文件:

<system.serviceModel> 
<client> 
    <endpoint binding="basicHttpBinding" 
      bindingConfiguration="Default" 
      contract="ServiceProxy.Login" 
      name="Login" /> 
</client> 
<bindings> 
    <basicHttpBinding> 
    <binding name="Default"> 
     <security mode="TransportWithMessageCredential"> 
     <transport clientCredentialType="None"/> 
     <message clientCredentialType="UserName" /> 
     </security> 
    </binding> 

    </basicHttpBinding> 
</bindings> 
</system.serviceModel> 

这里的SOAP请求:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
    <s:Header> 
    <!-- Removed --> 
    <ActivityId CorrelationId="c9363270-1b33-4ffe-90b0-427feebcebf6" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">cadd6a3c-7b36-46eb-9130-390227effc08</ActivityId> 
    <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> 
     <u:Timestamp u:Id="_0"> 
     <u:Created>2012-12-13T22:50:22.308Z</u:Created> 
     <u:Expires>2012-12-13T22:55:22.308Z</u:Expires> 
     </u:Timestamp> 
     <o:UsernameToken u:Id="uuid-91607d82-da2c-4004-93b6-baf5973ba057-1"> 
     <o:Username> 
      <!-- Removed--> 
     </o:Username> 
     <o:Password> 
      <!-- Removed--> 
     </o:Password> 
     </o:UsernameToken> 
    </o:Security> 
    </s:Header> 
    <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <LoginRequest xmlns="http://snipped.url/Services.xsd"></LoginRequest> 
    </s:Body> 
</s:Envelope> 

而这里的,使得WCF呛响应:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soapenv:Header> 
     <!-- Removed --> 
     <o:Security xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:mustUnderstand="1"> 
     <saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" AssertionID="id-94ef81a2eba3b246e284f72c3313e32ababe9482" IssueInstant="2012-12-13T22:50:23.930Z" Issuer="http://www.forumsys.com/sentry" MajorVersion="1" MinorVersion="1"> 
      <saml:Conditions NotBefore="2012-12-13T22:50:23.930Z" NotOnOrAfter="2012-12-14T08:50:23.930Z"></saml:Conditions> 
      <saml:AuthenticationStatement AuthenticationInstant="2012-12-13T22:50:23.930Z" AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password"> 
      <saml:Subject> 
       <saml:NameIdentifier> 
       <!-- Removed--> 
       </saml:NameIdentifier> 
       <saml:SubjectConfirmation> 
       <saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:sender-vouches</saml:ConfirmationMethod> 
       </saml:SubjectConfirmation> 
      </saml:Subject> 
      <saml:SubjectLocality> 
       <!-- Removed--> 
      </saml:SubjectLocality> 
      </saml:AuthenticationStatement> 
      <saml:AttributeStatement> 
      <saml:Subject> 
       <saml:NameIdentifier> 
       <!-- Removed--> 
       </saml:NameIdentifier> 
       <saml:SubjectConfirmation> 
       <saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:sender-vouches</saml:ConfirmationMethod> 
       </saml:SubjectConfirmation> 
      </saml:Subject> 
      <saml:Attribute AttributeName="SMSESSION" AttributeNamespace="http://www.forumsys.com/sentry"> 
       <saml:AttributeValue> 
       <!-- Removed--> 
       </saml:AttributeValue> 
      </saml:Attribute> 
      </saml:AttributeStatement> 
      </saml:Assertion> 
     <u:Timestamp xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" u:Id="_0"> 
      <u:Created>2012-12-13T22:50:22.308Z</u:Created> 
      <u:Expires>2012-12-13T22:55:22.308Z</u:Expires> 
     </u:Timestamp> 
     <o:UsernameToken xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" u:Id="uuid-91607d82-da2c-4004-93b6-baf5973ba057-1"> 
      <o:Username> 
      <!-- Removed--> 
      </o:Username> 
      <o:Password> 
      <!-- Removed--> 
      </o:Password> 
     </o:UsernameToken> 
     </o:Security> 
    </soapenv:Header> 
    <soapenv:Body> 
     <wn1:LoginResponse xmlns:wn1="http://snipped.url/Services.xsd"> 
     <wn1:Status>session counter updated</wn1:Status> 
     </wn1:LoginResponse> 
    </soapenv:Body> 
</soapenv:Envelope> 

上述反应是成功的响应并匹配在WSE2/3上运行的先前版本(这是出于其他原因我无法继续前进)。

如何让WCF确认上述响应有效?或者也许只是为了让它忽略它无法解析它的事实,我可以手动解析它。

我很难过!

更新#1:

我开始往下走的自定义客户端证书的路线。这看起来很有希望,如果有点复杂。

如果你想要走这条路......

1)查看MS系列文章在这里:http://msdn.microsoft.com/en-us/library/ms730868(v=vs.100).aspx

2)另见WCF样品WCF \扩展性\安全\ SamlTokenProvider。

3)采用这种方法博客文章:http://bronumski.blogspot.com/2011/11/this-has-been-hanging-around-in-my.html

这应该允许您使用SAML断言没有WIF。

更新#2:

见我的答案和低于最终的解决方案。

+0

您应该添加您的解决方案作为答案,以便您可以获得upvotes,以便将来的读者可以更轻松地找到答案。 –

+0

嗯。技术上亚龙给出了我接受的答案,我只是在OP中详细说明了最终的解决方案。如果我按照你的建议去做,那么不会把这些观点应用于我而不是Yaron? (不太熟悉SO如何做) – wes

回答

1

我建议,为了让saml不要使用wcf安全。只需通过自定义标题(可能使用消息检查器)将用户名添加到请求中,并使用相同的方法从响应中提取SAML。然后用同样的方法将saml推到每一个信封。

+0

谢谢!这正是我所需要的。在其他人的原始文章中添加更多详细信息。 – wes

0

最终跟随亚伦的建议,并写了一对夫妇自定义检查员的行为&行为。

使用proxy.ClientCredentials.UserName.UserName/Password是上面报告的原始异常的原因。它会在处理后续添加的行为之前尝试验证返回的SOAP,从而每次都会在SAML断言上产生响应验证错误。

第一行为/检查员有两个任务:

1)在请求侧,手动添加的UsernameToken节点;

2)在响应端,提取saml令牌;一定要从SOAP中删除任何有问题的“安全”XML节点,并重新处理回复(防止其他错误,如原来的帖子);稍后保存SAML响应。

第二个行为/检查器将共享的SAML断言注入剩余的请求中。

这里所需要的配置:

<basicHttpBinding> 
    <binding name="Default"> 
     <security mode="Transport"> 
     <transport clientCredentialType="None"/> 
     </security> 
    </binding> 
    </basicHttpBinding> 

下面是一些代码(注意去除ClientCredentials行为):

http://msdn.microsoft.com/en-us/library/aa717047(v=vs.100).aspx:你需要创建行为和检查员

var proxy = new LoginClient(); 
proxy.ChannelFactory.Endpoint.Behaviors.Remove<ClientCredentials>(); 
var initLogin = new InitialLoginMessageBehavior("username", "password"); 
proxy.Endpoint.Behaviors.Add(initLogin); 
var response = proxy.Login(); 

//use the SAML response 
var proxy2 = new OtherClient(); 
proxy2.ChannelFactory.Endpoint.Behaviors.Remove<ClientCredentials>(); 
proxy2.Endpoint.Behaviors.Add(new SamlAuthenticationMessageBehavior(initLogin.Saml)); 

var response2 = proxy2.DoSomethingElse(); 

一切

http://blogs.msdn.com/b/carlosfigueira/archive/2011/04/19/wcf-extensibility-message-inspectors.aspx