WCF 安全性之 自定义用户名密码验证

案例下载

http://download.csdn.net/detail/woxpp/4113172

客户端调用代码 通过代理类

代理生成 参见

http://www.cnblogs.com/woxpp/p/6232298.html

X509证书创建

http://www.cnblogs.com/woxpp/p/6232325.html

自定义用户名密码验证需要证书的支持

服务器端配置代码

复制代码
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary1.Service1" behaviorConfiguration="CustomBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/WcfServiceLibrary"/>
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- 除非完全限定,否则地址将与上面提供的基址相关 -->
        <endpoint address="net.tcp://localhost:8731/WcfServiceLibrary" binding="netTcpBinding" bindingConfiguration="TestNetTcpBinding" contract="WcfServiceLibrary1.IService1">
          <!-- 
              部署时,应删除或替换下列标识元素,以反映
              用来运行所部署服务的标识。删除之后,WCF 将
              自动推断相应标识。
          -->
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <!-- Metadata Endpoints -->
        <!-- 元数据交换终结点供相应的服务用于向客户端做自我介绍。 -->
        <!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除-->
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <bindings>
      <netTcpBinding>
        <binding name="TestNetTcpBinding">
          <security mode="Message">
            <message clientCredentialType="UserName"/>
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="CustomBehavior">
          <!-- 为避免泄漏元数据信息,
          请在部署前将以下值设置为 false 并删除上面的元数据终结点  -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- 要接收故障异常详细信息以进行调试,
          请将以下值设置为 true。在部署前设置为 false 
            以避免泄漏异常信息-->
          <serviceDebug includeExceptionDetailInFaults="False" />
          <serviceCredentials>
            <serviceCertificate findValue="TestServer" storeName="My" storeLocation="CurrentUser" x509FindType="FindBySubjectName"/>
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfServiceLibrary1.MyCustomValidator,WcfServiceLibrary1"/>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
复制代码

服务端自定义验证代码

复制代码
namespace WcfServiceLibrary1
{
    public class MyCustomValidator : UserNamePasswordValidator
    { 
        public override void Validate(string userName, string password)
        { 
            // validate arguments  
            if (string.IsNullOrEmpty(userName)) 
                throw new ArgumentNullException("userName"); 
            if (string.IsNullOrEmpty(password)) 
                throw new ArgumentNullException("password"); 
            // check if the user is not xiaozhuang 
            if (userName != "abcd1234" || password != "abcd1234")
                throw new SecurityTokenException("用户名或者密码错误!");
        }
    }
}
复制代码
复制代码
        private void btnTest_Click(object sender, EventArgs e)
        {
            //Service1Client client = new Service1Client();
            //txtMessage.Text = client.GetDataUsingDataContract(new WcfServiceLibrary1.CompositeType() { StringValue = "sssss" }).StringValue;

            NetTcpBinding binding2 = new NetTcpBinding();
            binding2.Security.Mode = SecurityMode.Message;
            binding2.Security.Message = new MessageSecurityOverTcp() { ClientCredentialType = MessageCredentialType.UserName };
            EndpointAddress endpoint = new EndpointAddress(new Uri("net.tcp://localhost:8731/WcfServiceLibrary"),
              EndpointIdentity.CreateDnsIdentity("TestServer"));
            ChannelFactory<IService1> factory = new ChannelFactory<IService1>(binding2, endpoint);
            factory.Credentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My,
              X509FindType.FindBySubjectName, "TestServer");
            factory.Credentials.UserName.UserName = "abcd1234";
            factory.Credentials.UserName.Password = "abcd1234"; 
            IService1 client = factory.CreateChannel();
            txtMessage.Text = client.GetDataUsingDataContract(new WcfServiceLibrary1.CompositeType() { StringValue = "sssss" }).StringValue;
            //B9DF5B912B8CF8EAB07A7BB9B0D17694522AB0CE
        }
复制代码

 

posted @   释迦苦僧  阅读(1578)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示