使用 WCF over HTTP 连接到受密码保护的服务器

发布于 2024-12-02 03:19:26 字数 3713 浏览 1 评论 0原文

您好,

我需要使用 WCF 将 ASP.NET MVC 应用程序连接到网络上的服务器。服务器受用户名和密码保护,但看起来它不是 https,而是简单的 http。

这是我到目前为止的代码:

public MyObject GetMyData(string id)
{
    ChannelFactory<MyIService> factory;
    ClientCredentials loginCredentials = new ClientCredentials();

    loginCredentials.UserName.UserName = "MyName";
    loginCredentials.UserName.Password = "MyPassword";

    factory = new ChannelFactory<ICFService>("MyData");

    var defaultCredentials = factory.Endpoint.Behaviors.Find<ClientCredentials>();
    factory.Endpoint.Behaviors.Remove(defaultCredentials); //remove default ones
    factory.Endpoint.Behaviors.Add(loginCredentials); //add required ones

    var proxy = factory.CreateChannel();
    var response = proxy.GetMyData(id);
    ((IDisposable)proxy).Dispose();

    return response as MyObject ;
}

并且它被放置在我的 web.config 中

  <system.serviceModel>
    <client>
      <endpoint address="http://MyUrl/"
                binding="webHttpBinding"
                behaviorConfiguration="MyData"
                contract="MyNameSpace.MyIService"
                name="MyData"/>
    </client>
    <behaviors>
      <endpointBehaviors>
        <behavior name="MyData">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>

  </system.serviceModel>

问题是我收到以下异常:

远程服务器返回错误:(401)未经授权。 描述:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其在代码中的来源的更多信息。 异常详细信息:System.Net.WebException:远程服务器返回错误:(401) 未经授权。

我知道我尝试与之通信的服务器仅当我的应用程序位于特定 IP 编号上时才会进行通信但这已经完成并且应该有效。

请提出建议

编辑1:

服务如下:

[ServiceContract]
[XmlSerializerFormat]
public interface ICFService
{
    [OperationContract]
    [WebGet(BodyStyle = WebMessageBodyStyle.Bare, 
        ResponseFormat = WebMessageFormat.Xml, 
        UriTemplate = "get?UID=12345.eu_vddsall_xml&MyId={MyId}&LANG=en")]
    CFExtendedDescription GetMyData(string MyId);

}

编辑2: 这是在 Firefox 中浏览 url 时对话框的样子。我不确定如何检查 Proxy.GetMyData 将使用的实际 url。

访问拒绝 请注意,这是一个示例,地址和“网站说”是其他内容。

我应该使用的网址如下所示:

http://bat.myserver.com/ag/get?UID=12345.eu_vddsall_xml&MyId=WRH421&LANG=sv

Edit3: 通过将傻瓜添加到 web.config,我们向前迈出了一步(感谢 Ladislav Mrnka):

<bindings>
  <webHttpBinding>
    <binding name="secured">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Basic" />
      </security>
    </binding>
  </webHttpBinding>
</bindings>

现在我们得到以下异常:

无法使用根名称“Binary”和根名称空间“”反序列化 XML 主体(用于操作'GetMyData' 和合同 ('ICFService', 'http://tempuri.org/')) 使用 XmlSerializer。确保与 XML 对应的类型添加到服务的已知类型集合中。 描述:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其在代码中的来源的更多信息。 异常详细信息:System.Runtime.Serialization.SerializationException:无法反序列化具有根名称“Binary”和根命名空间“”的 XML 主体(对于操作“GetMyData”和合约(“ICFService”,“http://tempuri.org/')) 使用 XmlSerializer。确保将与 XML 相对应的类型添加到服务的已知类型集合中。

首先,我认为远程服务器可能返回了一个 xml 文档,表明我位于错误的 IP 上,因此我将站点上传到正确的服务器(具有正确的IP),但我在那里得到同样的异常?

编辑4

创建了一个新问题:无法使用根名称“Binary”和根命名空间反序列化 XML 主体?

感谢 Ladislav Mrnka 的帮助!

Hi,

I need to connect my ASP.NET MVC application to a server on the net with WCF. The server is username and password protected but it appears that its not a https but a simple http.

This is the code I have so far :

public MyObject GetMyData(string id)
{
    ChannelFactory<MyIService> factory;
    ClientCredentials loginCredentials = new ClientCredentials();

    loginCredentials.UserName.UserName = "MyName";
    loginCredentials.UserName.Password = "MyPassword";

    factory = new ChannelFactory<ICFService>("MyData");

    var defaultCredentials = factory.Endpoint.Behaviors.Find<ClientCredentials>();
    factory.Endpoint.Behaviors.Remove(defaultCredentials); //remove default ones
    factory.Endpoint.Behaviors.Add(loginCredentials); //add required ones

    var proxy = factory.CreateChannel();
    var response = proxy.GetMyData(id);
    ((IDisposable)proxy).Dispose();

    return response as MyObject ;
}

And this is placed in my web.config

  <system.serviceModel>
    <client>
      <endpoint address="http://MyUrl/"
                binding="webHttpBinding"
                behaviorConfiguration="MyData"
                contract="MyNameSpace.MyIService"
                name="MyData"/>
    </client>
    <behaviors>
      <endpointBehaviors>
        <behavior name="MyData">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>

  </system.serviceModel>

The problem is that I get the following exception :

The remote server returned an error: (401) Unauthorized.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Net.WebException: The remote server returned an error: (401) Unauthorized.

I know that the server that I am trying to communicate with will only communicate if my application is placed on a specific IP nr but this is already done and should work.

Pleas advice

Edit1:

This is how the service looks like :

[ServiceContract]
[XmlSerializerFormat]
public interface ICFService
{
    [OperationContract]
    [WebGet(BodyStyle = WebMessageBodyStyle.Bare, 
        ResponseFormat = WebMessageFormat.Xml, 
        UriTemplate = "get?UID=12345.eu_vddsall_xml&MyId={MyId}&LANG=en")]
    CFExtendedDescription GetMyData(string MyId);

}

Edit2:
This is how the dialog looks like when browsing the url in firefox. Im not sure how to check the acctual url that the Proxy.GetMyData will use.

AccessDenied
Pleas note, this is an example, the adress and "The site says" is something else.

The Url that I am supose to use looks like this :

http://bat.myserver.com/ag/get?UID=12345.eu_vddsall_xml&MyId=WRH421&LANG=sv

Edit3:
By adding the foolowing to the web.config we got a step forward (thanks Ladislav Mrnka) :

<bindings>
  <webHttpBinding>
    <binding name="secured">
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Basic" />
      </security>
    </binding>
  </webHttpBinding>
</bindings>

Now we get the following exception instead :

Unable to deserialize XML body with root name 'Binary' and root namespace '' (for operation 'GetMyData' and contract ('ICFService', 'http://tempuri.org/')) using XmlSerializer. Ensure that the type corresponding to the XML is added to the known types collection of the service.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.Serialization.SerializationException: Unable to deserialize XML body with root name 'Binary' and root namespace '' (for operation 'GetMyData' and contract ('ICFService', 'http://tempuri.org/')) using XmlSerializer. Ensure that the type corresponding to the XML is added to the known types collection of the service.

First I thought that the remote server maby returned a xml document that shows that I am on the wrong IP so I uploaded the site to the correct server(with the correct ip) but I get the same exception there?

Edit 4

Created a new question : Unable to deserialize XML body with root name 'Binary' and root namespace?

Thanks Ladislav Mrnka for helping!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑梦风尘 2024-12-09 03:19:26

如果您不知道如何找到服务提供商,您应该询问服务提供商如何保证服务的安全。

您的网站似乎正在使用基本 HTTP 身份验证。对于此类身份验证,您需要创建自定义 webHttpBinding 配置:

<system.serviceModel>
  <client>
    <endpoint address="http://MyUrl/"
              binding="webHttpBinding"
              bindingConfiguration="secured"
              behaviorConfiguration="MyData"
              contract="MyNameSpace.MyIService"
              name="MyData"/>
  </client>
  <bindings>
    <webHttpBinding>
      <binding name="secured">
        <security mode="TransportCredentialOnly">
          <transport clientCredentialType="Basic" />
        </security>
      </binding>
    </webHttpBinding>
  </bindings>
  <behaviors>
    <endpointBehaviors>
      <behavior name="MyData">
        <webHttp/>
      </behavior>
    </endpointBehaviors>
  </behaviors>
</system.serviceModel>

You should ask service provider how is service secured if you don't know how to find it.

It looks like your site is using basic HTTP authentication. For such authentication you need to create custom webHttpBinding configuration:

<system.serviceModel>
  <client>
    <endpoint address="http://MyUrl/"
              binding="webHttpBinding"
              bindingConfiguration="secured"
              behaviorConfiguration="MyData"
              contract="MyNameSpace.MyIService"
              name="MyData"/>
  </client>
  <bindings>
    <webHttpBinding>
      <binding name="secured">
        <security mode="TransportCredentialOnly">
          <transport clientCredentialType="Basic" />
        </security>
      </binding>
    </webHttpBinding>
  </bindings>
  <behaviors>
    <endpointBehaviors>
      <behavior name="MyData">
        <webHttp/>
      </behavior>
    </endpointBehaviors>
  </behaviors>
</system.serviceModel>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文