zoukankan      html  css  js  c++  java
  • WCF基于用户名和密码安全成功测试

    目标:
    1.客户端与服务器端通信使用x509证书验证,但不用客户端安装证书。只需要服务器端配置好证书即可。
    2.验证使用用户名密码形式。

    操作:
    (这里的测试使用wcf项目模板缺省的服务,即只要新建一个使用vs2008自动生成的wcf项目就行了,

    它会自动生成有一个GetData方法,我就用这个方法进行测试)
    1.新建WCF服务应用程序.

    1.1生成一个服务器证书:运行Visual Studio 2008 命令提示工具:

    输入:makecert -r -pe -n "CN=MyServer" -sr LocalMachine -ss My -sky exchange执行。

    -sr LocalMachine 请一定保存到LodcalMachine中.目的就是到时如果你部署这个wcf服务的时候可以让IIS找到证书,

    反之,IIS会报找不到x509证书.

    2.配置web.config文件:
    这里要注意的是把storeLocation设为LocalMachine,原因也是到时需要部署的时候可以免掉很多麻烦,因为以后发布到iis时很可以不能正常验证到证书的私钥.

     1:  <system.serviceModel>
     2:      <bindings>
     3:        <wsHttpBinding>
     4:          <binding name="NewBinding0">
     5:            <security>
     6:              <message clientCredentialType="UserName" />
     7:            </security>
     8:          </binding>
     9:        </wsHttpBinding>
    10:      </bindings>
    11:      <services>
    12:        <service behaviorConfiguration="WcfService2.Service1Behavior"
    13:          name="WcfService2.Service1">
    14:          <endpoint address="" binding="wsHttpBinding" bindingConfiguration="NewBinding0"
    15:            contract="WcfService2.IService1">
    16:          </endpoint>
    17:          <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    18:        </service>
    19:      </services>
    20:      <behaviors>
    21:        <serviceBehaviors>
    22:          <behavior name="WcfService2.Service1Behavior">
    23:            <serviceMetadata httpGetEnabled="true" />
    24:            <serviceDebug includeExceptionDetailInFaults="false" />
    25:            <serviceCredentials>
    26:              <clientCertificate>
    27:                <authentication certificateValidationMode="None" />
    28:              </clientCertificate>
    29:              <serviceCertificate findValue="MyServer" storeLocation="LocalMachine" x509FindType="FindBySubjectName" />
    30:              <userNameAuthentication userNamePasswordValidationMode="Custom"
    31:                customUserNamePasswordValidatorType="WcfService2.MyUserNamePasswordValidator,WcfService2" />
    32:            </serviceCredentials>
    33:          </behavior>
    34:        </serviceBehaviors>
    35:      </behaviors>
    36:    </system.serviceModel>

    3.建造验证客户端用户名和密码的方法.

    这里注意的是必须与web.config文件中的customUserNamePasswordValidatorType=中的内容一致,

    格式是:"命名空间.方法名,命名空间"

    实际项目应用中这里应该是从数据库里确认用客是否合法。

     1:  namespace WcfService2 
     2:  { 
     3:      public class MyUserNamePasswordValidator : UserNamePasswordValidator 
     4:      { 
     5:          public override void Validate(string userName, string password) 
     6:          { 
     7:              if (userName != "jac" || password != "jac") 
     8:              { 
     9:                  throw new SecurityTokenException("Unknown Username or Password"); 
    10:              } 
    11:          } 
    12:      } 
    13:  }

    至此,wcf服务配置完成。

    4.新建一个asp.net项目,并添加服务引用这个wcf服务.

    5.修改asp.net项目的web.config文件(一定要在引用wcf服务后).

    添加一个endpointBehaviors:

     1:  <behaviors>
     2:    <endpointBehaviors>
     3:      <behavior name="jacBehavior">
     4:        <clientCredentials>
     5:          <serviceCertificate>
     6:            <authentication certificateValidationMode="None" />
     7:          </serviceCertificate>
     8:        </clientCredentials>
     9:      </behavior>
    10:    </endpointBehaviors>
    11:  </behaviors>

    然后让它生效,

    1:  <endpoint address="http://j-8de9be98d1184/Service1.svc" behaviorConfiguration="jacBehavior"
    2:   binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
    3:   contract="ServiceReference1.IService1" name="WSHttpBinding_IService1">

    以下是完整的asp.net客户端的web.config文件的system.serviceModel部份

     1:  <system.serviceModel>
     2:    <behaviors>
     3:      <endpointBehaviors>
     4:        <behavior name="jacBehavior">
     5:          <clientCredentials>
     6:            <serviceCertificate>
     7:              <authentication certificateValidationMode="None" />
     8:            </serviceCertificate>
     9:          </clientCredentials>
    10:        </behavior>
    11:      </endpointBehaviors>
    12:    </behaviors>
    13:    <bindings>
    14:      <wsHttpBinding>
    15:        <binding name="WSHttpBinding_IService1" closeTimeout="00:01:00"
    16:         openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
    17:         bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
    18:         maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text"
    19:         textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
    20:          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
    21:           maxBytesPerRead="4096" maxNameTableCharCount="16384" />
    22:          <reliableSession ordered="true" inactivityTimeout="00:10:00"
    23:           enabled="false" />
    24:          <security mode="Message">
    25:            <transport clientCredentialType="Windows" proxyCredentialType="None"
    26:             realm="" />
    27:            <message clientCredentialType="UserName" negotiateServiceCredential="true"
    28:             algorithmSuite="Default" establishSecurityContext="true" />
    29:          </security>
    30:        </binding>
    31:      </wsHttpBinding>
    32:    </bindings>
    33:    <client>
    34:      <endpoint address="http://j-8de9be98d1184/Service1.svc" behaviorConfiguration="jacBehavior"
    35:       binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
    36:       contract="ServiceReference1.IService1" name="WSHttpBinding_IService1">
    37:        <identity>
    38:          <certificate encodedValue="AwAAAAEA.....................eGtnWJsvtFQsEuzDYw==" />
    39:        </identity>
    40:      </endpoint>
    41:    </client>
    42:  </system.serviceModel>

    6.调用.

    1:  ServiceReference1.Service1Client sc = new WebApplication1.ServiceReference1.Service1Client(); 
    2:  sc.ClientCredentials.UserName.UserName = "jac"; 
    3:  sc.ClientCredentials.UserName.Password = "jac"; 
    4:  Label1.Text = sc.GetData(22);

    完成.

    工程文件下载:http://FunSL.com

    为了便使这种方式自由度更高,以下是服务器端的纯代码版本:

     1:  using System; 
     2:  using System.Collections.Generic; 
     3:  using System.Linq; 
     4:  using System.Text; 
     5:  using System.ServiceModel; 
     6:  using System.IdentityModel.Selectors; 
     7:  using System.ServiceModel.Description; 
     8:  
     9:  namespace wcf.username 
    10:  { 
    11:      class Program 
    12:      { 
    13:          static void Main(string[] args) 
    14:          { 
    15:              EndpointAddress endp = new EndpointAddress("http://localhost/myservice"); 
    16:  
    17:              WSHttpBinding ws = new WSHttpBinding(); 
    18:              ws.Security.Mode = SecurityMode.Message; 
    19:              ws.Security.Message.ClientCredentialType = MessageCredentialType.UserName; 
    20:  
    21:              ServiceMetadataBehavior behavior = new ServiceMetadataBehavior(); 
    22:              behavior.HttpGetEnabled = true; 
    23:              behavior.HttpGetUrl = new Uri("http://localhost/myservice/mex"); 
    24:  
    25:              ServiceHost sh = new ServiceHost(typeof(serverdo), new Uri(endp.ToString())); 
    26:  
    27:              sh.Description.Behaviors.Add(behavior); 
    28:  
    29:              sh.Credentials.ClientCertificate.Authentication.CertificateValidationMode =  
    30:                  System.ServiceModel.Security.X509CertificateValidationMode.None; 
    31:  
    32:  
    33:              sh.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = 
    34:                   System.ServiceModel.Security.UserNamePasswordValidationMode.Custom; 
    35:  
    36:              sh.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new checkUserName(); 
    37:  
    38:              sh.Credentials.ServiceCertificate.SetCertificate( 
    39:                  System.Security.Cryptography.X509Certificates.StoreLocation.LocalMachine,  
    40:                  System.Security.Cryptography.X509Certificates.StoreName.My, 
    41:                  System.Security.Cryptography.X509Certificates.X509FindType.FindBySubjectName, "MyServer"); 
    42:  
    43:              sh.AddServiceEndpoint(typeof(Iservice), ws, endp.ToString()); 
    44:              sh.Open(); 
    45:  
    46:              Console.WriteLine("ok"); 
    47:              Console.Read(); 
    48:          } 
    49:      } 
    50:  
    51:      class checkUserName:UserNamePasswordValidator 
    52:      { 
    53:          public override void Validate(string userName, string password) 
    54:          { 
    55:              if (userName != "jac" && password != "jac") 
    56:              { 
    57:                  throw new FaultException("userName and passWord be error"); 
    58:              } 
    59:          } 
    60:      } 
    61:  
    62:      [ServiceContract] 
    63:      interface Iservice 
    64:      { 
    65:          [OperationContract] 
    66:          string test(string msg); 
    67:      } 
    68:  
    69:      class serverdo:Iservice 
    70:      { 
    71:          #region Iservice 成员 
    72:  
    73:          public string test(string msg) 
    74:          { 
    75:              Console.WriteLine("user inter:" + msg); 
    76:  
    77:              return "user inter:" + msg; 
    78:          } 
    79:  
    80:          #endregion 
    81:      } 
    82:  
    83:  }
  • 相关阅读:
    Jdk 1.6 在线 API 中文版
    数据库的最简单实现
    互联网公司GitHub repo 语言使用情况
    Chrome浏览器查看 iframe信息 OpenFrame
    PostgreSQL 保存json,jsonb类型
    修改PS1变量
    postgres json
    PostgreSQL PL/Python 和 PL/Postgres 函数互相调用
    转:CentOS 6.x 挂载读写NTFS分区(fuse-ntfs-3g)
    CentOS 7 设置静态IP
  • 原文地址:https://www.cnblogs.com/jacle169/p/2810782.html
Copyright © 2011-2022 走看看