我正在努力为我的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!
答案 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(以及样本)可以为您提供更多信息。