我刚开始使用Microsoft Service Bus。现在我的个人挑战是我在下班后,在我自己的时间等这样做,这意味着我正在使用虚拟机和非域名电脑。这些人都是工作组。
我取得了相当不错的成功,特别是在我偶然发现这个链接之后:Microsoft Service Bus 1.0 unable to communicate with a server outside the client's domain
这家伙提供了一个非常需要的推动,让我能够使用命名空间来创建队列等。
然而,我去了QueueClient.Send()函数,我仍然得到了(我稍微解释了一下)。
"The token provider was unable to provide a security token while accessing 'https://Windows2008Server:9355/ServiceBusDefaultNamespace/$STS/Windows/'. Token provider returned message: ''.
上面链接中的相同代码就是我用于消息工厂的代码。所以我的问题是,有没有人对如何通过这个发送工作有任何想法?
如果我能解决这个小问题,那么我就可以开始看到Service Bus真正能做到的事了。
非常感谢!
尼克
与以前相同的问题,将我的代码更改为:
TokenProvider localUserTokenProvider = WindowsTokenProvider.CreateWindowsTokenProvider(connBuilder.StsEndpoints,new System.Net.NetworkCredential("LocalServer", "LocalPassword"));
MessagingFactory messageFactory = MessagingFactory.Create(connBuilder.GetAbsoluteRuntimeEndpoints(), localUserTokenProvider);
NamespaceManager namespaceManager = new NamespaceManager(connBuilder.GetAbsoluteManagementEndpoints(), localUserTokenProvider);
所以,看起来我仍然需要在他们两个上拥有相同的帐户......
答案 0 :(得分:2)
如果您的客户端和服务器位于不同的计算机上,则可能存在证书信任问题。您必须使用已安装的服务器计算机从服务器计算机导出服务总线服务器CA,打开Windows Server PowerShell控制台的服务总线并使用 Get-SBAutoGeneratedCA cmdlet,然后将其导入受信任的根目录客户端计算机的证书颁发机构存储。
This page提供了有关如何导出/导入它们以启用远程客户端方案的更多信息。
答案 1 :(得分:2)
我明白了。在这种情况下,由于您在两侧都使用了Windows,因此您不需要OAuthTokenProvider。您可以使用Windows令牌提供程序,只需确保以下内容: - 您传递的凭据必须存在于服务器中 - 请勿在凭证中包含任何域或工作组信息。
您需要像这样配置它(示例假设您正在使用连接字符串的配置文件):
TokenProvider localUserTokenProvider = WindowsTokenProvider.CreateWindowsTokenProvider(
connBuilder.StsEndpoints,
new System.Net.NetworkCredential (userName, password));
This page提供了有关如何使用Service Bus Server“离线”工作的更多信息。
答案 2 :(得分:1)
我弄清楚发生了什么,至少在一定程度上......
我必须使用与我登录到Win8框(dev)的凭据相同的W2k8服务器。
如果我尝试发送这样的参数:
//namespaceManager.Settings.TokenProvider = TokenProvider.CreateOAuthTokenProvider(new Uri[] { new Uri("https://ServerName:9355") }, new NetworkCredential("ServerLocalUser", "ServerLocalUserPwd", "ServerName"));
//messageFactory.GetSettings().TokenProvider = TokenProvider.CreateOAuthTokenProvider(new Uri[] { new Uri("https://ServerName:9355") }, new NetworkCredential("ServerLocalUser", "ServerLocalPWD", "ServerName"));
然后它将无法正常工作。任何想法为什么它发送我的登录凭据而不使用ServerLocalUser / Pwd / Name组合?
我通过查看事件日志找到了这个......
答案 3 :(得分:0)
这就是我为使事情发挥作用所做的一切。
我开始在我的开发机器(Win8 / Studio2012)和我的服务器(Win2k8R2)上创建相同的本地用户帐户。我导出了上面引用的客户端证书(实际上是2到3次)并根据需要导入。一旦我有一个良好的连接工作,我开始支持。删除了我的Win8盒子上的本地帐户等等。然后这一切都开始神奇地工作了。
关于我的环境的一些事情。我正在使用VMWare Fusion完成所有这些工作。 (是的Fusion)。 VM机器在网络上都配置了NAT,没有静态IP。
不知道如何,但它正在发挥作用。我先做了消息。我想如果我可以得到消息,那么我可以去找Pub / Sub主题......那就是下一个。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.ServiceBus;
using Microsoft.ServiceBus.Messaging;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Diagnostics;
using System.Security;
namespace Test_Service_Bus
{
public static class Util
{
public static void SetCertificatePolicy()
{
ServicePointManager.ServerCertificateValidationCallback += RemoteCertificateValidate;
}
private static bool RemoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
{
System.Console.WriteLine("Warning, trust any certificate");
return true;
}
}
class Program
{
static string ServerFQDN = "SVRNICK"; //System.Net.Dns.GetHostEntry(string.Empty).HostName;
static int HttpPort = 9355;
static int TcpPort = 9354;
static string ServiceNameSpace = "ServiceBusDefaultNamespace";
const string QueueName = "ServiceBusQueueSample";
static void Main(string[] args)
{
SDKVersion();
}
static void SDKVersion()
{
ServiceBusConnectionStringBuilder connBuilder = new ServiceBusConnectionStringBuilder();
connBuilder.ManagementPort = HttpPort;
connBuilder.RuntimePort = TcpPort;
connBuilder.Endpoints.Add(new UriBuilder() { Scheme = "sb", Host = ServerFQDN, Path = ServiceNameSpace }.Uri);
connBuilder.StsEndpoints.Add(new UriBuilder() { Scheme = "https", Host = ServerFQDN, Port = HttpPort, Path = ServiceNameSpace }.Uri);
TokenProvider localUserTokenProvider = WindowsTokenProvider.CreateWindowsTokenProvider(connBuilder.StsEndpoints, new System.Net.NetworkCredential("ServerLocalAcct", "ServerLocalPassword"));
MessagingFactory messageFactory = MessagingFactory.Create(connBuilder.GetAbsoluteRuntimeEndpoints(), localUserTokenProvider);
NamespaceManager namespaceManager = new NamespaceManager(connBuilder.GetAbsoluteManagementEndpoints(), localUserTokenProvider);
NamespaceManager.CreateFromConnectionString(connBuilder.ToString());
if (namespaceManager == null)
{
Console.WriteLine("\nUnexpected error: NamespaceManager is NULL");
return;
}
Console.WriteLine("Checking if queue exists");
if (namespaceManager.QueueExists(QueueName))
{
Console.WriteLine("Queue exists, let's delete it so we can start over again");
namespaceManager.DeleteQueue(QueueName);
}
Console.WriteLine("And create a new queue");
namespaceManager.CreateQueue(QueueName);
// create a message client
QueueClient myQueueClient = messageFactory.CreateQueueClient(QueueName);
Console.WriteLine("Feeding messages");
for (int i = 0; i < 1000; i++)
{
if (i % 100 == 0)
Console.WriteLine("Messages sent: {0}", i.ToString());
// send to message broker
using (BrokeredMessage sendMessage = new BrokeredMessage("Hello world. " + i.ToString()))
{
sendMessage.Label = "Label_" + i.ToString(); ;
myQueueClient.Send(sendMessage);
}
}
BrokeredMessage receivedMessage = myQueueClient.Receive(TimeSpan.FromSeconds(5));
while (receivedMessage != null)
{
Console.WriteLine(string.Format("Message Received: Body={0}", receivedMessage.GetBody<string>()));
receivedMessage.Complete();
receivedMessage = myQueueClient.Receive(TimeSpan.FromSeconds(5));
}
// Close things down.
Console.WriteLine("Closing down message");
if (messageFactory != null)
{
messageFactory.Close();
}
}
}
}