WCF身份验证服务
Windows Communication Foundation (WCF) 身份验证服务使你能够使用ASP.NET成员资格,从可以发送和使用SOAP消息的任何应用程序中对用户进行身份验证。这可以包括不使用.NET Framework的应用程序。因此,这些不同的应用程序的用户不需要对每个应用程序使用单独的凭据。用户在使用任意客户端应用程序时,均可通过提供相同的凭据登录到应用程序中。本节就使用WCF身份验证服务的几个关键点做实践性分析。
创建WCF身份验证服务
System.Web.ApplicationServices.AuthenticationService是.NET提供的默认身份验证服务类。AuthenticationService类包含只应通过WCF服务访问的四个方法:IsLoggedIn、Login、Logout和 ValidateUser方法。若要调用这些方法,请启用Web服务器上的身份验证服务,然后将WCF兼容的客户端应用程序连接到Web服务。
若要使用户登录,请将用户凭据传递给Login方法。如果凭据有效,AuthenticationService类创建一个身份验证Cookie;如果身份验证Cookie尚未过期,并且知道该用户的凭据已经过身份验证,则不必再次验证凭据。
注意 不能通过AuthenticationService类使用无Cookie身份验证。
AuthenticationService可引发两个事件:Authenticating和CreatingCookie。当验证用户凭据时发生Authenticating事件。为Authenticating事件创建一个事件处理程序以自定义如何验证用户凭据。在验证完用户凭据后设置身份验证Cookie时发生CreatingCookie事件。为CreatingCookie事件创建一个事件处理程序以自定义身份验证Cookie。
ValidateUser方法检查用于身份验证的用户凭据,但该方法不返回身份验证票证。当用户先前已登录且必须检查凭据在新的应用程序会话开始时是否仍然有效时,请使用ValidateUser方法。
现在新建一个.svc文件,如果使用默认的System.Web.ApplicationServices.AuthenticationService类提供成员资格验证服务,可以删除默认生成的接口文件和类文件,然后修改.svc文件,修改后的内容如下所示:
<%@ ServiceHost Language="C#"
Service="System.Web.ApplicationServices.ProfileService"
%>
如果要实现自定义的成员资格服务,只需要为Authenticating事件创建一个事件处理程序即可。
首先,创建如代码清单10-28所示的Authenticating事件处理程序。
代码清单10-28 Authenticating事件处理程序
void AuthenticationService_Authenticating(object sender, System.Web.ApplicationServices.AuthenticatingEventArgs e)
{
if (e.UserName.IndexOf("@xuanhun.com") >= 0)
{
e.Authenticated = Membership.Providers["xuanhunSqlProvider"].ValidateUser(e.UserName, e.Password);
}
elseif (e.UserName.IndexOf("@xuanbing.com") >= 0)
{
e.Authenticated = Membership.Providers["xuanbingSqlProvider"].ValidateUser(e.UserName, e.Password);
}
else
{
e.Authenticated = Membership.Provider.ValidateUser(e.UserName, e.Password);
}
e.AuthenticationIsComplete = true;
}
以上代码所示的Authenticating事件处理程序中,使用三个成员资格提供程序来验证用户,分别是自定义的xuanbingSqlProvider、xuanhunSqlProvider和配置文件中配置的默认的成员资格提供程序。验证之后设置当前用户的验证状态。
在编写完Authenticating事件处理程序后,需要在Global.asax文件的Application_Start方法中绑定Authenticating事件的处理程序。代码如下所示:
void Application_Start(object sender, EventArgs e)
{
System.Web.ApplicationServices.AuthenticationService.Authenticating +=
new EventHandler<System.Web.ApplicationServices.AuthenticatingEventArgs>(AuthenticationService_Authenticating);
}
启用身份验证服务
若要使上面创建的服务生效,必须在配置文件中做相关的配置。如何配置WCF服务的细节这里不做讲解,请参考相关WCF开发资料。
在configSections元素和appSettings元素之间添加一个新的system.web.extensions元素,然后向system.web.extensions元素中添加一个scripting元素,在scripting元素中,通过webServices节启用身份验证、配置文件和角色服务。代码清单10-29给出了一个简单的配置示例。
代码清单10-29 配置身份验证服务
<system.web.extensions>
<scripting>
<webServices>
<authenticationService enabled="true"
requireSSL = "true"/>
</webServices>
</scripting>
</system.web.extensions>
<system.serviceModel>
<services>
<service name="System.Web.ApplicationServices.AuthenticationService"
behaviorConfiguration="AuthenticationServiceTypeBehaviors">
<endpoint contract=
"System.Web.ApplicationServices.AuthenticationService"
binding="basicHttpBinding"
bindingConfiguration="userHttps"
bindingNamespace="http://xuanhun.net/ApplicationServices/membership"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="userHttps">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="AuthenticationServiceTypeBehaviors">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment
aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
在代码清单10-29的配置中,首先通过设置<authenticationService enabled="true" requireSSL = "true"/>来启用身份验证服务,并要求通过SSL来通信。之后在services元素中定义终结点协定,在 behaviors 元素中定义服务行为。在配置文件的最后,serviceHostingEnvironment配置节中设置aspNetCompatibilityEnabled="true",该配置用来指示在应用程序中运行的所有WCF服务在 ASP.NET兼容模式中运行。除了上面的配置之外,还必须为ASP.NET应用启用Forms身份验证。此时可以使用默认的或者自定义的验证程序来验证用户信息了。
自定义身份验证Cookie
身份验证服务将在已验证用户凭据之后且在已设置身份验证Cookie之前引发CreatingCookie事件。通过为CreatingCookie创建事件处理程序并自行管理身份验证Cookie,可以自定义Cookie。通过传递给事件处理程序的CreatingCookieEventArgs对象可以访问用户名、密码和自定义凭据。代码清单10-30为CreatingCookie事件创建事件处理程序的示例。
代码清单10-30 CreatingCookie事件处理程序
void AuthenticationService_CreatingCookie(object sender,
System.Web.ApplicationServices.CreatingCookieEventArgs e)
{
FormsAuthenticationTicket ticket = new
FormsAuthenticationTicket
(1,
e.UserName,
DateTime.Now,
DateTime.Now.AddMinutes(30),
e.IsPersistent,
e.CustomCredential,
FormsAuthentication.FormsCookiePath);
string encryptedTicket =
FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie
(FormsAuthentication.FormsCookieName,
encryptedTicket);
cookie.Expires = DateTime.Now.AddMinutes(30);
HttpContext.Current.Response.Cookies.Add(cookie);
e.CookieIsSet = true;
}
在代码清单10-30中,通过将CustomCredential属性的值添加到UserData属性来自定义身份验证Cookie。
下面在Global.asax文件的Application_Start方法中,绑定CreatingCookie事件的处理程序,代码如下所示:
void Application_Start(object sender, EventArgs e)
{
System.Web.ApplicationServices.AuthenticationService.CreatingCookie
+= new EventHandler<System.Web.ApplicationServices.CreatingCookieEventArgs>
(AuthenticationService_CreatingCookie);
}
经过了上面的代码编写和配置,现在可以使用WCF服务来完成身份验证了。
---------------------------------------------------注:本文部分内容改编自《.NET 安全揭秘》