使用nunit从IP获取身份验证令牌

时间:2012-08-17 17:04:38

标签: authentication nunit wif

我正在努力为我的WCF数据服务/ ODATA服务器添加WIF支持,我要做的第一件事就是创建一个nUnit测试,它将某种身份传递给所述服务器。我相信这属于活跃客户的范畴:没有用户界面;我想打电话给app.config建立的提供商(谷歌,雅虎,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方法返回MessageSecurityException,其内部异常类型为FaultException,注意“Invalid Request”。 FaultException有一个Code = Name = Sender和Namespace = http://www.w3.org/2003/05/soap-envelope,它有一个SubCode,Name = InvalidRequest,Namespace = http://schemas.xmlsoap。组织/ 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!

1 个答案:

答案 0 :(得分:0)

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

例如,我不确定Google是否实施了WS-Trust(WIF正在使用什么)。 LiveID可能在某处有一个WS-Trust端点,但不确定它是否得到官方支持/记录(例如,您获得的错误可能是因为LiveID不知道您的RP: http:// localhost: 60711 /服务;因此无法为其发出令牌。)

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

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

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

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