[WCF Security] 4. 用户名/密码身份验证

X.509 比较适合验证 "客户机" 的身份,而另外一方面,我们可能需要针对具体的 "用户" 进行验证。本文将记述基于 "用户名/密码" 方式的身份验证开发步骤。

1. 服务器数字证书

我们同样需要为服务器准备一个数字证书。

D:/>makecert -r -pe -n "CN=MyServer" -ss My -sky exchange


2. 创建服务

[ServiceContract]
public interface IService
{
  [OperationContract]
  string Test();
}

public class MyService : IService
{
  public string Test()
  {
    return "Server:" + DateTime.Now.ToString();
  }
}

public class WcfTest
{
  public static void Test()
  {
    ServiceHost host = new ServiceHost(typeof(MyService));
    host.Open();
  }
}



我们通过继承 UserNamePasswordValidator 来创建一个自定义验证器。

public class MyUserNamePasswordValidator : UserNamePasswordValidator
{
  public override void Validate(string userName, string password)
  {
    if (userName != "user" || password != "pwd")
    {
      throw new SecurityTokenException("Unknown Username or Password");
    }
  }
}


接 下来创建服务器配置文件,我们使用 WsHttpBinding,采取 Message 安全模式。其他的设置还包括 certificateValidationMode、userNamePasswordValidationMode、 customUserNamePasswordValidatorType 等。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="NewBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceCredentials>
            <clientCertificate>
              <authentication certificateValidationMode="None" />
            </clientCertificate>
            <serviceCertificate findValue="MyServer" storeLocation="CurrentUser"
              x509FindType="FindBySubjectName" />
            <userNameAuthentication userNamePasswordValidationMode="Custom"
              customUserNamePasswordValidatorType=
                "Learn.Library.WCF.MyUserNamePasswordValidator, Learn.Library" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="Binding1">
          <security mode="Message">
            <message clientCredentialType="UserName" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="NewBehavior" name="Learn.Library.WCF.MyService">
        <endpoint address="service" binding="wsHttpBinding" bindingConfiguration="Binding1"
          name="username" contract="Learn.Library.WCF.IService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8080" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>



3. 创建客户端

启动服务器后,创建客户端代理文件。注意自动生成的客户端配置文件中包含了服务器数字证书的相关信息。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="username">
          <security mode="Message">
            <message clientCredentialType="UserName" negotiateServiceCredential="true"
              algorithmSuite="Default" establishSecurityContext="true" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://localhost:8080/service" binding="wsHttpBinding"
        bindingConfiguration="username" contract="ConsoleApplication1.localhost.IService"
        name="username">
        <identity>
          <certificate encodedValue="AwAA...IgFHqYA==" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>
</configuration>


开始调用服务,注意将 CertificateValidationMode 设置为 None,当然也可以写到配置文件中。

using (ServiceClient client = new ServiceClient())
{
  client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode =
    X509CertificateValidationMode.None;

  client.ClientCredentials.UserName.UserName = "user";
  client.ClientCredentials.UserName.Password = "pwd";

  Console.WriteLine(client.Test());
}


OK! 测试通过! [lol]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值