اعتبارسنجی سرویس های WCF
نویسنده: مسعود پاکدل
تاریخ: ۱۳۹۲/۱۰/۱۹ ۸:۴۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
[ServiceContract]
public interface IBookService
{
[OperationContract]
int GetCountOfBook();
} [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class BookService : IBookService
{
public int GetCountOfBook()
{
return 10;
}
} class Program
{
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(BookService));
var binding = new BasicHttpBinding();
host.AddServiceEndpoint(typeof(IBookService), binding, "http://localhost/BookService");
host.Open();
Console.Write("BookService host");
Console.ReadKey();
}
} static void Main(string[] args)
{
Thread.Sleep(2000);
BasicHttpBinding binding = new BasicHttpBinding();
ChannelFactory<IBookService> channel = new ChannelFactory<IBookService>(binding, new EndpointAddress("http://localhost/BookService"));
Console.WriteLine("Count of book: {0}", channel.CreateChannel().GetCountOfBook());
Console.ReadKey();
}
تا اینجا هیچ گونه اعتبار سنجی انجام نشد. برای پیاده سازی اعتبار سنجی باید یک سری تنظیمات بر روی Binding و Hosting سمت سرور و البته کلاینت بر قرار شود. فایل Program پروزه Service را باز نمایید و محتویات آن را به صورت زیر تغییر دهید:
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(BookService));
var binding = new BasicHttpBinding();
binding.Security = new BasicHttpSecurity();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = System.ServiceModel.Security.UserNamePasswordValidationMode.Custom;
host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNamePasswordValidator();
host.AddServiceEndpoint(typeof(IBookService), binding, "http://localhost/BookService");
host.Open();
Console.Write("BookService host");
Console.ReadKey();
} public class CustomUserNamePasswordValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
if (userName != "Masoud" || password != "Pakdel")
throw new SecurityException("Incorrect userName or password");
}
}
این خطا از آن جا ناشی میشود که تنظیمات کلاینت و سرور از نظر امنیتی با هم تناسب ندارد. در نتیجه باید تنظیمات Binding کلاینت و سرور یکی شود. برای این کار کد زیر را به فایل Program سمت کلاینت اضافه میکنیم:
static void Main(string[] args)
{
Thread.Sleep(2000);
BasicHttpBinding binding = new BasicHttpBinding();
binding.Security = new BasicHttpSecurity();
binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
ChannelFactory<IBookService> channel = new ChannelFactory<IBookService>(binding, new EndpointAddress("http://localhost/BookService"));
channel.Credentials.UserName.UserName = "WrongUserName";
channel.Credentials.UserName.Password = "WrongPassword";
Console.WriteLine("Count of book: {0}", channel.CreateChannel().GetCountOfBook());
Console.ReadKey();
} channel.Credentials.UserName.UserName = "WrongUserName"; channel.Credentials.UserName.Password = "WrongPassword";
proxy.ChannelFactory.Credentials.UserName.UserName = "WrongUserName"; proxy.ChannelFactory.Credentials.UserName.Password = "WrongPassword";
<behaviors>
<serviceBehaviors>
<behavior name="yourServiceNameBehavior">
<serviceDebug includeExceptionDetailInFaults ="true"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyCustomUserNameValidator, service" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel> <serviceCertificate findValue="localhost" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />