0

我正在努力为我的 WCF 数据服务/ODATA 服务器添加 WIF 支持,我想做的第一件事是创建一个 nUnit 测试,它将某种身份传递给所述服务器。我相信这属于活跃客户的范畴:没有用户界面;我想调用 app.config 已建立的提供商(Google、Yahoo、Windows Live 或其他提供商)来获取我的身份令牌。坦率地说,这并不重要,只是它或多或少总是可以访问的,并且没有管理来运行测试。(如果有一些主机应用程序可以包含在我的解决方案中以充当 IP,我会非常满意。)

我所有现有的测试都直接使用 HttpRequest ——我没有使用生成的客户端。在创建 HttpRequest 对象时,我会检查是否已经有一个身份验证令牌可以放入我的标头中。如果没有,我正在尝试这样的事情:

using (WSTrustChannelFactory factory = new WSTrustChannelFactory(
   new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
   new EndpointAddress(new Uri("https://dev.login.live.com/wstlogin.srf"))))
{
   factory.Credentials.UserName.UserName = "MYUSERNAME";
   factory.Credentials.UserName.Password = "MYPASSWORD";
   factory.TrustVersion = TrustVersion.WSTrust13;

   WSTrustChannel channel = null;
   try
   {
     var rst = new RequestSecurityToken
     {
       RequestType = WSTrust13Constants.RequestTypes.Issue,
       AppliesTo = new EndpointAddress("http://localhost:60711/Service"),
       KeyType = WSTrust13Constants.KeyTypes.Bearer,
     };

    channel = (WSTrustChannel)factory.CreateChannel();
    return channel.Issue(rst);
  }
  finally
  {
    if (null != channel)
    {
      channel.Abort();
    }
    factory.Abort();
  }
}

所以开始...我什至不知道我是否针对 IP 的正确 URI,但是当我更改它时,我得到了 404,所以我想我可能在正确的轨道上。目前,channel.Issue 方法返回一个带有 FaultException 类型内部异常的 MessageSecurityException,并注明“无效请求”。FaultException 有一个 Name=Sender 和 Namespace=http://www.w3.org/2003/05/soap-envelope 的 Code,然后它有一个 Name=InvalidRequest 和 Namespace=http://schemas.xmlsoap 的 SubCode。 org/ws/2005/02/信任。我不知道如何处理这些信息。:)

如果我问一个非常基本的问题,我很抱歉。我只关注了几天的身份验证,还不知道我的方法。谢谢你的帮助!

编辑——解决方案

Eugenio 是对的——我正在做一些重量级的事情,它更多的是集成测试的东西。我放弃了 Google/Yahoo/Live 的东西,并找到了SelfSTS的修改版本,我将它拼凑到我的项目中。我还不完全明白发生了什么,但我取回了一个 SAML 令牌。这是最终代码:

var binding = new WS2007HttpBinding();

binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.NegotiateServiceCredential = true;

using (var trustChannelFactory = new WSTrustChannelFactory(binding, new EndpointAddress(new Uri("http://localhost:8099/STS/Username"), new DnsEndpointIdentity("adventureWorks"), new AddressHeaderCollection())))
{
  trustChannelFactory.Credentials.UserName.UserName = MYUSERNAME;
  trustChannelFactory.Credentials.UserName.Password = MYPASSWORD;
  trustChannelFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
  trustChannelFactory.TrustVersion = TrustVersion.WSTrust13;

  WSTrustChannel channel = null;

  try
  {
    var rst = new RequestSecurityToken(WSTrust13Constants.RequestTypes.Issue)
    {
      AppliesTo = new EndpointAddress("http://localhost:60711/Service"),
      KeyType = WSTrust13Constants.KeyTypes.Bearer
    };

    channel = (WSTrustChannel)trustChannelFactory.CreateChannel();
    GenericXmlSecurityToken token = channel.Issue(rst) as GenericXmlSecurityToken;
    ((IChannel)channel).Close();
    channel = null;

    trustChannelFactory.Close();

    string tokenString = token.TokenXml.OuterXml;
    return tokenString;
  }
  finally
  {
    if (null != channel)
    {
      ((IChannel)channel).Abort();
    }
    trustChannelFactory.Abort();
  }
}

(这段代码也是从我得到修改后的 SelfSTS 的同一个地方提取的——谢谢,Wade Wegner!)

我不确定“adventureWorks”的使用。我使用的 SelfSTS 版本作为配置中的 issuername,但我没有检查是否有任何相关性。

所以......现在破解我的实际服务器,以便它可以弄清楚如何处理 SAML!

4

1 回答 1

0

并非所有这些 IP 都支持活动呼叫。即使他们这样做,协议也可能不兼容。

例如,我不确定 Google 是否实现了 WS-Trust(WIF 在后台使用的是什么)。LiveID 可能在某处有一个 WS-Trust 端点,但不确定它是否受到官方支持/记录(例如,您收到的错误可能是因为 LiveID 不知道您的 RP:http://localhost:60711/Service ; 因此不能为其颁发令牌)。

对于像这样的多个 IP,应用程序通常会嵌入 Web 浏览器并将其用于所有令牌协商(例如使用 WS-Federation)。他们通常依靠专门的 STS 来处理协议转换(例如 Windows Azure 访问控制服务)

无论如何,对于单元测试来说,你正在做的事情听起来有点重量级。这听起来更像是您想要自动化的集成测试。

也许您可以从自己的自定义(假)STS 开始。您可以在其中控制一切并模拟不同的输出(例如不同的声明等)

本章: http: //msdn.microsoft.com/en-us/library/hh446528(和示例)可以为您提供更多信息。

于 2012-08-17T18:01:42.007 回答