6

我刚开始玩微软服务总线。现在我个人的挑战是我在几个小时后,在我自己的时间等,这意味着我正在使用虚拟机和非域电脑。这些人都是工作组。

我已经取得了相当不错的成功,尤其是在我偶然发现这个链接之后:Microsoft Service Bus 1.0 unable to communication 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);

所以,看起来我仍然需要在他们两个上拥有相同的帐户......

4

4 回答 4

2

如果您的客户端和服务器在不同的机器上,您可能会遇到证书信任问题。您必须使用已安装从服务器计算机导出服务总线服务器 CA,打开 Windows Server PowerShell 控制台的服务总线并使用Get-SBAutoGeneratedCA cmdlet,然后将其导入客户端计算机的受信任的根证书颁发机构存储中.

此页面包含有关如何导出/导入它们以启用远程客户端方案的更多信息。

于 2013-03-15T20:49:22.503 回答
2

我懂了。在这种情况下,由于您在两侧都使用窗口,因此不需要 OAuthTokenProvider。您可以使用 Windows 令牌提供程序,只需确保以下几点: - 您传递的凭据必须存在于服务器中 - 不要在凭据中包含任何域或工作组信息。

您需要像这样配置它(示例假设您正在为连接字符串使用配置文件):

TokenProvider localUserTokenProvider = WindowsTokenProvider.CreateWindowsTokenProvider(
            connBuilder.StsEndpoints,
            new System.Net.NetworkCredential (userName, password));

此页面包含有关如何使用服务总线服务器“脱机”工作的更多信息。

于 2013-03-20T21:21:14.447 回答
1

我知道发生了什么,至少在某种程度上......

我必须使用与我登录到我的 Win8 框(开发)相同的凭据来访问 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 组合?

我通过查看事件日志发现了这一点...

于 2013-03-20T03:19:49.437 回答
0

这是我为使事情正常工作所做的。

我开始在我的开发机器(Win8/Studio2012)和我的服务器(Win2k8R2)上创建相同的本地用户帐户。我导出了上面引用的客户端证书(实际上是 2 或 3 次)并根据需要导入。一旦我建立了良好的连接工作,我就开始退出。删除了我的 Win8 机器上的本地帐户等。然后一切都开始神奇地工作。

关于我周围的一些事情。我正在使用 VMWare 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();
                }
            }
        }
    }
于 2013-03-22T01:52:10.473 回答