无配置文件的WCF服务自托管与自定义验证

在没有IIS的环境中,如何创建一个安全的WCF服务,并使用Channel Factory进行调用,是一个常见的问题。本文将介绍如何使用Visual Studio 2010 Express创建一个完全自托管的WCF服务,并通过自定义验证进行安全调用。

最近,遇到了一个需要在没有IIS的环境中创建一个安全的WCF服务的挑战。只有Visual Studio 2010 Express,并且需要创建一个完全独立的服务,不依赖于任何证书。

解决方案是创建一个自托管WCF服务,使用自定义验证,并使用Channel Factory进行调用。在创建这个POC的过程中,遇到了一些错误,于是开始在网上搜索类似的POC。找到了一些,但大多数都不是可以直接运行的,要么只有服务器端代码,要么只有客户端代码,或者需要在app.config中进行一些更改。

WCF服务器端

将创建一个自托管WCF服务,使用传输安全(用户名/密码)进行保护。

using System; using System.ServiceModel; using System.ServiceModel.Security; using System.IdentityModel.Tokens; using System.IdentityModel.Selectors; using System.Security.Principal; using System.ServiceModel.Description; namespace SecurWCFSelfHosting { class Program { [ServiceContract] public interface IDemoService { [OperationContract] int Add(int x, int y); } public class DemoService : IDemoService { public int Add(int x, int y) { return x + y; } } static void Main(string[] args) { Uri httpUrl = new Uri("http://localhost:999/MyService/"); ServiceHost host = new ServiceHost(typeof(DemoService), httpUrl); BasicHttpBinding http = new BasicHttpBinding(); http.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly; http.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; host.AddServiceEndpoint(typeof(IDemoService), http, ""); host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom; host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new MyCustomValidator(); ServiceMetadataBehavior smb = host.Description.Behaviors.Find(); if (smb == null) { smb = new ServiceMetadataBehavior { HttpGetEnabled = true }; host.Description.Behaviors.Add(smb); } host.Open(); Console.WriteLine(DateTime.Now.ToString() + " Service is host at " + httpUrl.ToString()); Console.WriteLine("The service is running in the following account: " + WindowsIdentity.GetCurrent().Name); Console.WriteLine("Press to terminate service."); Console.ReadLine(); } } public class MyCustomValidator : UserNamePasswordValidator { public override void Validate(string userName, string password) { if (userName != "h" || password != "p") { throw new SecurityTokenException("Validation Failed!"); } Console.WriteLine(DateTime.Now.ToString() + " Validation success for user :" + userName); } } }

客户端

using System; using System.ServiceModel; using System.ServiceModel.Description; namespace WCFConsumeByChannelFactory { class Program { static void Main(string[] args) { EndpointAddress Serviceaddress = new EndpointAddress("http://localhost:999/MyService/"); BasicHttpBinding httpBinding = new BasicHttpBinding(); httpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly; httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic; ChannelFactory myChannelFactory = new ChannelFactory(httpBinding, Serviceaddress); var defaultCredentials = myChannelFactory.Endpoint.Behaviors.Find(); myChannelFactory.Credentials.UserName.UserName = "h"; myChannelFactory.Credentials.UserName.Password = "p"; IDemoService wcfClient1 = myChannelFactory.CreateChannel(); double s = wcfClient1.Add(73, 22); Console.WriteLine(s.ToString()); ((IClientChannel)wcfClient1).Close(); Console.ReadKey(); } } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485