本菜鸟目前对 Microsoft SmartClient 技术非常感兴趣,最近仔细分析了 Microsoft 编写的 IssueVision 和 TaskVision 这两个 SmartClient Demo ,个人感觉上才开始接触 SmartClient 的朋友最好先分析 TaskVision ,在有一定的基础上在分析 IssueVision 。这样学习效果可能比较好。为了让才开始接触 SmartClinet 的朋友少走些弯路,同时也为了与学习 Microsoft SmartClient 技术的朋友更好的进行技术交流,本菜鸟将把这几个星期 IssuesVision 和 TaskVision 的学习心得与各位同行进行分享。
当客户端调用 XML Web services 时,为了安全因素,通常会要求客户端进行身份验证,只有通过身份验证才有权限调用 XML Web services 提供的方法。 IssueVision 使用 SoapHeader 传递 XML Web services 自定义身份验证数据。 TaskVision 使用 FormsAuthenticationTicket 的 Forms 身份验证 cookie (包含身份验票)来获取调用 XML Web services 方法的权限。下面将对这两种 XML Web services 自定义身份验证数据的方法进行详细的讲解。
** ** ** SoapHeader ** ** 传递 XML Web services 自定义身份验证数据
**
SOAP 标头提供了一种方法,用于将数据传递到 XML Web services 方法或从 XML Web services 方法传递数据,条件是该数据不直接与 XML Web services 方法的主功能相关。例如,一个 XML Web servicess 可能包含若干个 XML Web services 方法,而每个方法都需要自定义的身份验证方案。您不用将参数添加到每个需要自定义身份验证方案的 XML Web services 方法,而可以将引用从 ** SoapHeader ** 派生的类的 SoapHeaderAttribute 应用于每个 XML Web services 方法。从 ** SoapHeader ** 派生的类的实现处理该自定义身份验证方案。按照此方式, XML Web services 方法使用 SOAP 标头来仅实现特定于它的功能并添加其他功能。 IssueVision 就是利用 ** SoapHeader ** 的这种能力来实现 XML Web services 自定义身份验证数据传递。
IssueVision 如何利用 SoapHeader 传递数据进行 WebService 自定义身份验证数据:
1 :创建从 ** SoapHeader ** 派生的类,表示传入 SOAP 标头的数据。
[IssueVision 解决方案中 IssueVisionWebCS 项目的 CredentialSoapHeader 类实现 ]
using System.Web.Services.Protocols;
namespace IssueVision.Web
{
public class CredentialSoapHeader : SoapHeader
{
private string m_username;
private string m_password;
public string Username
{
get{ return m_username;}
set{ m_username = value;}
}
public string Password
{
get{ return m_password;}
set{ m_password = value;}
}
}
}
2 : 将 CredentialSoapHeader 类一个成员添加到实现 XML Web servicess 的类或 XML Web servicess 客户端代理类。
[IssueVision 解决方案中 IssueVisionWebCS 项目的 IssueVisionServices 类实现 ]
Namespace IssueVision.Web
{
public class IssueVisionServices : Web Service
{
private CredentialSoapHeader m_credentials
public CredentialSoapHeader Credentials
{
get{ return m_credentials;}
set{ m_credentials = value;}
}
… …
}
}
3 :将 SoapHeaderAttribute 应用于 XML Web services 方法或代理类中的对应方法
[IssueVision 解决方案中 IssueVisionWebCS 项目的 IssueVisionServices 类实现 ]
Namespace IssueVision.Web
{
public class IssueVisionServices : Web Service
{
… …
[WebMethod(Description="Returns the lookup tables for IssueVision.")]
[SoapHeader(“Credentials”)]
public IVDataSet GetLookupTables()
{
SecurityHelper.VerifyCredentials( this );
return new IVData().GetLookupTables();
}
}
}
4 :在客户端代码中调用 XML Web services 方法前,要求在代理类中设置 SOAP 标头。
[IssueVision 解决方案中 IssueVision 项目的 WebServicesLayer 类调用 XML Web services 方法并在代理类中设置 SOAP 标头 ]
Namespace IssueVision.Web
{
private static IssueVisionServices GetWebServiceReference( string username, string password)
{
IssueVisionServices dataService = new IssueVisionServices();
//
1<replacewithwse>
2
3CredentialSoapHeader header = new CredentialSoapHeader();
4
5header.Username = username;
6
7header.Password = password;
8
9dataService.CredentialSoapHeaderValue = header;
10
11//</replacewithwse>
InitWebServiceProxy(dataService);
return dataService;
}
public static IVDataSet GetLookupTables()
{
IVDataSet data = null ;
IssueVisionServices dataService = GetWebServiceReference();
try
{
data = dataService.GetLookupTables();
}
… …
}
}
** FormsAuthenticationTicket ** ** 的 Forms 身份验证传递 XML Web services 自定义身份验证数据
**
** ** FormsAuthenticationTicket 类提供一种创建 FormsAuthenticationModule 使用的 Forms 身份验证 cookie (包含身份验票)并读取其值的方法。 TaskVision 就是利用 FormsAuthenticationTicket 来实现 XML Web services 自定义身份验证数据传递。
TaskVision 如何利用 FormAuthenticationTicket 传递数据进行 WebService 自定义身份验证数据:
1 :在 XML Web services 端将客户端传入参数进行验证,验证通过,则添加新的 Cache 对象,并把验证的返回值加密保存在 Cache 中。
[TaskVision 解决方案中 TaskVisionWsCsVs 项目的 AuthService 类实现 ]
[WebMethod()]
public string GetAuthorizationTicket( string userName, string password )
{
// try to authenticate the user
string userID;
try
{
userID = SqlHelper.ExecuteScalar(dbConn, "AuthenticateUser", userName, password).ToString();
}
finally
{
dbConn.Close();
}
if (userID == null )
{
// The user name and password combination is not valid.
return null ;
}
// create the ticket
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(userID, false , 1);
string encryptedTicket = FormsAuthentication.Encrypt(ticket);
// get the ticket timeout in minutes
AppSettingsReader configurationAppSettings = new AppSettingsReader();
int timeout = ( int ) configurationAppSettings.GetValue("AuthenticationTicket.Timeout", typeof ( int ));
// cache the ticket
Context.Cache.Insert(encryptedTicket, userID, null , DateTime.Now.AddMinutes(timeout), TimeSpan.Zero);
return encryptedTicket;
}
2 :将验证值应用于 XML Web services 方法或代理类中的对应方法
[TaskVision 解决方案中 TaskVisionWsCsVs 项目的 AuthService 类实现 ]
private bool IsTicketValid( string ticket , bool IsAdminCall)
{
if (ticket == null || Context.Cache[ticket] == null )
{
return false ;
}
else
{
int userID = int .Parse(FormsAuthentication.Decrypt(ticket).Name);
… …
}
}
[WebMethod()]
public UserInformation UpdateUser( string ticket, UserInformation userInfo)
{
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 94.3pt; TEXT-INDENT: -22.5pt; TEXT-ALIGN: