您的位置:首页 > 其它

WCF安全操练(3)--WCF客户端

2009-08-31 15:50 232 查看
我的WCF客户端用的silverlight3实现,原因是silverlight3中加入了WCF服务安全性的支持。

首先,在你客户端的开发机器上安装为WCF制做好的证书,可以直接把服务器上的证书导入到新机器中。导入的储存区最好是本地计算机的受信任的根证书颁发机构中,一劳永逸。

新建silverlight项目,为silverlight工程添加服务引用,在生成的ServiceReferences.ClientConfig配置文件中会看到类似的结果,如果没生成,请手动写入,或是仔细检查发布完的WCF服务是否用的basicHttpBinding方式。

<configuration >
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IServiceForMyself" maxBufferSize="2147483647"
                    maxReceivedMessageSize="2147483647">
                    <security mode="TransportWithMessageCredential" />
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="https://10.11.41.87/WcfServiceForMyself/ServiceForMyself.svc"
                binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IServiceForMyself"
                contract="ServiceReference2.IServiceForMyself" name="BasicHttpBinding_IServiceForMyself" />
        </client>
    </system.serviceModel>
</configuration>


接着让你的工程显示所有文件,打开被引用的WCF服务中的service.wsdl文件,看最后的几行文件,在<soap:address>结点中有你服务的地址,如https://dqgb-ldap001.dqgb.ldap2009.local/WcfServiceForMyself/ServiceForMyself.svc,由于我在内网中开发项目,这个地址是不会被正确解析的,所以要在整个解决方案中用IP地址替换掉dqgb-ldap001.dqgb.ldap2009.local。

下面给出客户端的代码:

XAML文件:

<UserControl xmlns:dataInput="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input"  x:Class="TestSilverlight3.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
  <Grid x:Name="LayoutRoot" HorizontalAlignment="Left" VerticalAlignment="Top">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
      <TextBox Width="300" Height="Auto" Name="tb_box" Grid.Row="0" Grid.Column="0"></TextBox>
      <Button Width="30" Height="Auto" Content="调用" Click="Button_Click" Grid.Row="0" Grid.Column="1"></Button>
      <dataInput:Label Width="300" Height="Auto" Name="lbl_message" Grid.Row="0" Grid.Column="2"></dataInput:Label>
  </Grid>
</UserControl>


XAML.CS文件:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;

namespace TestSilverlight3
{
    public partial class MainPage : UserControl
    {
        ServiceReference2.ServiceForMyselfClient myClient;
        public MainPage()
        {
            InitializeComponent();
            myClient = new TestSilverlight3.ServiceReference2.ServiceForMyselfClient();
            myClient.ClientCredentials.UserName.UserName = "Admin";
            myClient.ClientCredentials.UserName.Password = "123";
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            myClient.PrintMessageCompleted += new EventHandler<TestSilverlight3.ServiceReference2.PrintMessageCompletedEventArgs>(myClient_PrintMessageCompleted);
            myClient.PrintMessageAsync(tb_box.Text);
        }

        void myClient_PrintMessageCompleted(object sender, TestSilverlight3.ServiceReference2.PrintMessageCompletedEventArgs e)
        {
            lbl_message.Content = e.Result;
        }
    }
}


到这里客户端程序完成。接下来是注意事项。

第一,就是前面提到的,WCF服务要用BasicHttpBinding。这是因为对 Silverlight 可以访问的服务类型存在一些限制。如果没有使用 “启用 Silverlight 的 WCF 服务”模板创建 WCF 服务,必须确保 WCF 服务配置为支持它的 BasicHttpBinding。

第二,当在承载 Silverlight 应用程序的网站之外的任何位置创建服务时,都会产生跨域问题。在 Silverlight 应用程序和服务之间进行跨域调用时会出现安全漏洞,且必须由相应跨域策略明确启用该跨域调用。

当在 Visual Studio 中调试多个单独的 Web 应用程序项目时,常常会出现这种情况,因为已向每个 Web 应用程序分配了不同的端口号。例如,您的 Silverlight 应用程序可能位于 http://localhost:1111 上,而您的服务可能位于http://localhost:2222 上。即使计算机名相同 (localhost),端口号的不同也足以造成跨域问题。

第三,跨域问题的解决。在承载服务的域的根目录中放置一个 clientaccesspolicy.xml 文件,以配置服务允许跨域访问。 配置文件内客如下:

<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
  <cross-domain-access>
    <policy>
      <allow-from http-request-headers="*">
        <domain uri="http://*"/>
      </allow-from>
      <grant-to>
        <resource path="/" include-subpaths="true"/>
      </grant-to>
    </policy>
  </cross-domain-access>
</access-policy>


这里要注意的是加入了<domain uri="http://*/">的配置,这是因为客户端是http的程序,而WCF是https的,若允许从某个 HTTP 应用程序访问 HTTPS 服务,则需要将 <domain uri="http://*/">元素放入<allow-from>元素。

OK,到这里为止,WCF的安全操练全部完成。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐