案例下載html
http://download.csdn.net/detail/woxpp/4113172安全
客戶端調用代碼 經過代理類服務器
代理生成 參見tcp
http://www.cnblogs.com/woxpp/p/6232298.htmlide
X509證書建立spa
http://www.cnblogs.com/woxpp/p/6232325.html.net
自定義用戶名密碼驗證須要證書的支持代理
服務器端配置代碼調試
<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>
服務端自定義驗證代碼code
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 }