网站建设狼雨,wordpress mysql_query,滁州网站开发,显示网站目录概述 今天在做Master Data Service#xff08;后面简称MDS#xff09;项目时需要通过WCF来使用MDS的API#xff0c;从而对MDS的数据进行操作。在这个过程中#xff0c;遇到了一个棘手的问题#xff0c;就是在客户端调用Web Service时的身份认证问题#xff0c;于是乎对WC… 概述 今天在做Master Data Service后面简称MDS项目时需要通过WCF来使用MDS的API从而对MDS的数据进行操作。在这个过程中遇到了一个棘手的问题就是在客户端调用Web Service时的身份认证问题于是乎对WCF的认证方式做了一个简单的了解。在这里还要感谢蔡总陪我加班一起解决问题在蔡总的大力支持下问题得以解决。我们解决问题的方式采用了客户端用户名密码的方式来进行身份认证这只是诸多WCF认证方式当中的一种。 用户名密码认证的三种模式 基于用户名/密码的用户凭证通过类型UserNamePasswordClientCredential表示。而在ClientCredentials中只读属性UserName表示这样一个用户凭证。可以按照Windows凭证的方式为ChannelFactoryTChannel或者ClientBaseTChannel基于用户名/密码凭证。 public class ClientCredentials
{//其他成员public UserNamePasswordClientCredential UserName { get; }
}
public sealed class UserNamePasswordClientCredential
{//其他成员public string Password {get; set; }public string UserName { get; set; }
}用户名/密码凭证在客户端的设置很容易但是我们关心的是服务端采用怎样的机制来验证这个凭证。WCF提供了如下三种方式来验证凭证中用户名是否和密码相符 Windows将用户名和密码映射为Windows帐号和密码采用Windows认证MembershipProvider利用配置的MembershipProvider验证用户名和密码自定义通过继承抽象类UsernamePasswordValidator自定义用户名/密码验证器进行验证。WCF通过枚举UserNamePasswordValidationMode定了上述三种用户名/密码认证模式。该枚举定义如下其中Windows是默认选项。 public enum UserNamePasswordValidationMode
{Windows,MembershipProvider,Custom
} 上述三种认证模式的设置最终通过之前提到过的ServiceCredentials这一服务行为进行设置的。从下面的定义我们可以看出ServiceCredentials定义了只读属性UserNameAuthentication用于基于用户名/密码认证的相关设置。属性的类型为UserNamePasswordServiceCredential定义其中的UserNamePasswordValidationMode属性表示采用的认证模式。如果选择了需要通过属性MembershipProvider设置采用的MembershipProvider。如果选择了Custom则需要通过CustomUserNamePasswordValidator属性指定你自定义的UserNamePasswordValidator对象。 public class ServiceCredentials: SecurityCredentialsManager, IServiceBehavior
{//其他成员public UserNamePasswordServiceCredential UserNameAuthentication { get; }
}
public sealed class UserNamePasswordServiceCredential
{//其他成员public UserNamePasswordValidator CustomUserNamePasswordValidator { get; set; }public MembershipProvider MembershipProvider { get; set; }public UserNamePasswordValidationMode UserNamePasswordValidationMode { get; set;} 通过MembershipProvider进行用户名密码的认证 Membership是ASP.NET中一个重要的模块旨在进行基于用户名/密码的认证和对应的帐号管理。Membership采用策略设计模式所有的API通过几个静态Membership类暴露出来而相应的功能实现在具体的Membership提供者中。所有的提供者继承自同一个抽象类MembershipProvider。ASP.NET提供了两种类型的提供者SqlMembershipProvider和ActiveDirectoryMembershipProvider。前者将用户存储于SQL Server数据库中而后者则直接建立在AD之上本实例采用SqlMembershipProvider在前面一个实例演示中我们创建了以计算服务为场景的解决方案现在我们直接沿用它。 首要的任务是在用于存储帐户信息的SQL Server数据库为此可以先在本地SQL Server创建一个空的数据库假设起名为AspNetDb。接着需要在该数据库中创建SqlMembershipProvider所需的数据表和相应的存储过程。这些数据库对象的创建需要借助aspnet_regsql.exe这个工具。你只需要以命令行的方式执行如下aspnet_regsql.exe无需任何参数相应的向导就会出现。 在向导弹出的前两个窗体中保持默认设置直接点击“下一步”后会出现一个数据库选择窗体。此时你需要选择我们刚刚创建的数据库点击“确认”后相关的数据库对象会为你创建出来。 这些创建出来的数据表可以同时服务于多个应用所有每一个表中都具有一个名称为ApplicationId的字段来明确该条记录对应的应用。而所有应用记录维护在aspnet_Applications这么一个表中。现在需要通过执行下面一段SQL脚本在该表中添加一条表示应用的记录。将其命名为MembershipAuthenticationDemo。 INSERT INTO [aspnet_Applications]([ApplicationName],[LoweredApplicationName],[ApplicationId],[Description])
VALUES(MembershipAuthenticationDemo,membershipauthenticationdemo,NEWID(),) 现在数据库方面已经准备就绪接着来完成编程和配置方面的工作。不打算从新创建一个解决方案而是直接对之前演示的实例进行改造。我们采用自我寄宿的方式由于Membership隶属于ASP.NET所以需要添加System.Web.dll的引用如果采用的是.NET Frameowrk 4.0本例所示的配置也是基于该版本则还需额外添加对System.Web.ApplicationServices.dll的引用。接下来需要在服务寄宿方面所做的工作就是将下面一段配置整个拷贝到app.config中。 ?xml version1.0?
configurationconnectionStringsadd nameAspNetDb connectionStringServer.; DatabaseAspNetDb; Uidsa; Pwdpassword//connectionStringssystem.webmembership defaultProvidermyProviderprovidersadd namemyProvider typeSystem.Web.Security.SqlMembershipProvider, System.Web, Version4.0.0.0, Cultureneutral,
PublicKeyTokenb03f5f7f11d50a3a connectionStringNameAspNetDb applicationNameMembershipAuthenticationDemo
requiresQuestionAndAnswerfalse//providers/membership/system.websystem.serviceModelbindingsws2007HttpBindingbinding nameuserNameCredentialBindingsecurity modeMessagemessage clientCredentialTypeUserName//security/binding/ws2007HttpBinding/bindingsservicesservice nameArtech.WcfServices.Services.CalculatorService behaviorConfigurationmembershipAuthenticationendpoint addresshttp://127.0.0.1/calculatorservice bindingws2007HttpBinding
bindingConfigurationuserNameCredentialBinding contractArtech.WcfServices.Contracts.ICalculator//service/servicesbehaviorsserviceBehaviorsbehavior namemembershipAuthenticationserviceCredentialsserviceCertificate storeLocationLocalMachine storeName My x509FindTypeFindBySubjectName findValueYueXu-PC/userNameAuthentication userNamePasswordValidationModeMembershipProvider membershipProviderNamemyProvider//serviceCredentials/behavior/serviceBehaviors/behaviors/system.serviceModel
/configuration 至此在我们创建的数据库中并没有用户帐户记录。为了演示认证效果我们需要创建相关用户帐户记录。为了方便我直接将相关的代码写在了服务寄宿的代码中。如下面的代码片断所示在对服务进行寄宿之前我通过调用Membership的静态方法CreateUser创建了一个用户名、密码和Email分别为xuyue、password01和xuyue1000hotmail的帐号。 if (Membership.FindUsersByName(xuyue).Count 0)
{Membership.CreateUser(xuyue, password01, xuyue1000hotmail.com);
}
using (ServiceHost host new ServiceHost(typeof(CalculatorService)))
{host.Open();Console.Read();
} 接下来我们需要对客户端的配置进行相应的调整整个配置内容如下面的XML片断所示。对于这段配置有一点需要注意的是终结点应用了一个名称为peerTrustSvcCertValidation的行为该行为中将服务证书认证模式设置成PeerTrust所以你需要通过MMC证书管理单元的导出/导入功能将YueXu-PC证书导入到“受信任人Trusted People”存储区。 ?xml version1.0?
configurationsystem.serviceModelbindingsws2007HttpBindingbinding nameuserNameCredentialBindingsecurity modeMessagemessage clientCredentialTypeUserName//security/binding/ws2007HttpBinding/bindingsclientendpoint namecalculatorService behaviorConfigurationpeerTrustSvcCertValidation
addresshttp://127.0.0.1/calculatorservice bindingws2007HttpBinding
bindingConfigurationuserNameCredentialBinding contractArtech.WcfServices.Contracts.ICalculatoridentitycertificateReference storeLocationLocalMachine storeName My x509FindTypeFindBySubjectName findValueYueXu-PC//identity/endpoint/clientbehaviorsendpointBehaviorsbehavior namepeerTrustSvcCertValidationclientCredentialsserviceCertificateauthentication certificateValidationModePeerTrust//serviceCertificate/clientCredentials/behavior/endpointBehaviors/behaviors/system.serviceModel
/configuration 最后我们来编写如下一段客户端进行服务调用的程序。在下面的代码中我进行了两次服务调用。但是创建服务代理对象的ChannelFactoryICalculator被设置了不同的用户名凭证。其中第一个是正确的用户名和密码后一个却指定了一个根本不存在的用户名。 using (ChannelFactoryICalculator channelFactory new ChannelFactoryICalculator(calculatorService))
{UserNamePasswordClientCredential credential channelFactory.Credentials.UserName;credential.UserName xuyue;credential.Password password01;ICalculator calculator channelFactory.CreateChannel();calculator.Add(1, 2);Console.WriteLine(服务调用成功...);
}
using (ChannelFactoryICalculator channelFactory new ChannelFactoryICalculator(calculatorService))
{UserNamePasswordClientCredential credential channelFactory.Credentials.UserName;credential.UserName wrongName;credential.Password wrongPWD;ICalculator calculator channelFactory.CreateChannel();try{calculator.Add(1, 2);}catch{Console.WriteLine(服务调用失败...);}
} 输出结果 1: 服务调用成功... 2: 服务调用失败... 转载于:https://www.cnblogs.com/hainange/archive/2011/08/02/6153588.html