WCF身份验证之用户名密码认证

WCF支持多种认证技术,例如Windowns认证、X509证书、Issued Tokens、用户名密码认证等,在跨Windows域分布的系统中,用户名密码认证是比较常用的,要实现用户名密码认证,就必须需要X509证书,用来加密用户名和密码。

  1. 创建数字证书

    makecert -sr localmachine -ss My -n CN=ejiyuan -sky exchange -pe -r。

  2. 创建服务代码

[ServiceContract]
    public interface ICalculator
    {
        [OperationContract]
        double add(double x, double y); } public class CalculatorService : ICalculator { public double add(double x, double y) { return x + y; } } class Program { static void Main(string[] args) { ServiceHost _serviceHost = new ServiceHost(typeof(CalculatorService)); _serviceHost.Opened += (s, q) => { Console.WriteLine("服务已启动"); Console.Read(); }; _serviceHost.Open(); } }

3.设置安全验证模式

<bindings>
      <netTcpBinding>
        <binding name="nonSessionBinding"> <!--当前绑定的安全认证模式--> <security mode="Message" > <!--定义消息级安全性要求的类型,为证书--> <message clientCredentialType="UserName" /> </security> </binding> </netTcpBinding> </bindings>

4.设置服务凭据值

<behaviors>
      <serviceBehaviors >
        <behavior name="CalculatorServiceBehavior" > <serviceCredentials> <!--指定一个 X.509 证书,用户对认证中的用户名密码加密解密--> <serviceCertificate findValue="CN=ejiyuan" x509FindType="FindBySubjectDistinguishedName" storeLocation="LocalMachine" storeName="My"/> <clientCertificate> <!--自定义对客户端进行证书认证方式 这里为 None--> <authentication certificateValidationMode="None"/> </clientCertificate> <!--自定义用户名和密码验证的设置--> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Wcf.Extensions.Security.UserNamePasswordValidator,Wcf.Extensions.Security" /> </serviceCredentials> </behavior> </serviceBehaviors> </behaviors>

5.自定义证书验证 
通过继承自’System.IdentityModel.Selectors.UserNamePasswordValidator’,然后我们重写里面的’Validate’方法来实现用户名密码认证逻辑

public class UserNamePasswordValidator : System.IdentityModel.Selectors.UserNamePasswordValidator
    {
        public override void Validate(string userName, string password) { if (userName != "ejiyuan" || password != "123456") { throw new System.IdentityModel.Tokens.SecurityTokenException("Unknown Username or Password"); } } }

6.客户端代码

class Program
    {
        static void Main(string[] args) { CalculatorClient client = new CalculatorClient(); //指定认证的用户名和密码 client.ClientCredentials.UserName.UserName = "ejiyuan"; client.ClientCredentials.UserName.Password = "123456"; var q = client.add(1, 2); Console.WriteLine(client.add(1,2)); Console.Read(); } }

7.客户端配置信息(自动生成的)

<system.serviceModel>
        <bindings>
            <netTcpBinding> <binding name="NetTcpBinding_ICalculator" > <security mode="Message"> <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" /> <message clientCredentialType="UserName" /> </security> </binding> </netTcpBinding> </bindings> <client> <endpoint address="net.tcp://192.168.101.13:8000/calculatorservice" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ICalculator" contract="ServiceReference1.ICalculator" name="NetTcpBinding_ICalculator"> <identity> <certificate encodedValue="AwAAAAEAAAAUAAAAgvtzbyRkxIGFn4UuyxD2+XJsJl8gAAAAAQAAAPQBAAAwggHwMIIBWaADAgECAhB/oj2gX287pUAmeLEVtWucMA0GCSqGSIb3DQEBBAUAMBIxEDAOBgNVBAMTB2VqaXl1YW4wHhcNMTAwNTI4MDkyNjQzWhcNMzkxMjMxMjM1OTU5WjASMRAwDgYDVQQDEwdlaml5dWFuMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfOgnw6Vs7gS52Gsud0WsuFOoDeF4+4DL1HFIpQupdExtIkWwY2v2/t/pWHRRvPE/aPf3M6axUYaT4pQqPXBHQR1lb0Hi6XLUGkzsEk7tjiEMEkpt+/8rQIdtXlmmry7yDixoX8PKEd5cGAISjEdbVKJqjQnC55rQXeDYlIXoqlwIDAQABo0cwRTBDBgNVHQEEPDA6gBCTu+dYQbdaauBGEk3SjJ5FoRQwEjEQMA4GA1UEAxMHZWppeXVhboIQf6I9oF9vO6VAJnixFbVrnDANBgkqhkiG9w0BAQQFAAOBgQA1jOywoJ5Xh6B6W3Vw7xPa9A6AH0WtedXPd4YbCU465UdKeP5G2HtKLpS20MnkU6lIh22lxMnb3WGZh70l5Sg1Hl0j/SklLKtOXzeQnVLaPundd9RS1TD/hHwVyu+89cr0866etfGwI9IDpwjhj5ixT3VUHI3eGrXRj+IGx8/W8Q==" /> </identity> </endpoint> </client> </system.serviceModel>

备注:基于UserNamePasswordValidator的认证方式,Validator中可以知道相应的UserName和Password,在Service中直接使用OperationContext.Current.ServiceSecurityContext.PrimaryIdentity即可获取当前登录用户信息。

猜你喜欢

转载自www.cnblogs.com/ztb123/p/9270489.html