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即可获取当前登录用户信息。

你可能感兴趣的:(WCF)