[原創(chuàng)]IssueVision 學習筆記(一)-----使用SoapHeader傳遞Web Serivices自定義的身份驗證數(shù)據(jù)
發(fā)表時間:2024-06-21 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]在調(diào)用Web Serivices時,往往需要身份驗證,使得通過驗證的用戶才能調(diào)用你Web Serivices中的方法.當然你可以通過將參數(shù)添加到每個需要自定義身份驗證方案的Web services方法中去,這需要花費很大的精力.IssueVision 中使用了非常常用而且有效便捷的方法-----使...
在調(diào)用Web Serivices時,往往需要身份驗證,使得通過驗證的用戶才能調(diào)用你Web Serivices中的方法.當然你可以通過將參數(shù)添加到每個需要自定義身份驗證方案的Web services方法中去,這需要花費很大的精力.IssueVision 中使用了非常常用而且有效便捷的方法-----使用SoapHeader來實現(xiàn)自定義身份驗證數(shù)據(jù)的傳遞.
SoapHeader提供了一種方法,用于將數(shù)據(jù)傳遞到Web services方法或從Web services方法傳遞數(shù)據(jù),條件是該數(shù)據(jù)不直接與Web services 方法的主功能相關(guān). 你不用將參數(shù)添加到每個需要自定義身份驗證方案的Web services 方法,而可以將引用從 SoapHeader 派生的類的 SoapHeaderAttribute 應(yīng)用于每個Web services 方法。從 SoapHeader 派生的類的實現(xiàn)處理該自定義身份驗證方案. IssueVision 就是利用SoapHeader的這種能力來實現(xiàn)自定義身份驗證數(shù)據(jù)傳遞的.
我們來看一下如何利用SoapHeader來傳遞數(shù)據(jù).
1. 首先需要在服務(wù)中定義一個從 SOAPHeader 派生的類,表示傳入 SOAP 標頭的數(shù)據(jù).
IssueVision 在中IssueVisionWeb項目(此項目用于發(fā)布Web Services)中通過創(chuàng)建CredentialSoapHeader類來實現(xiàn)第一步.
CredentialSoapHeader.cs
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. 將服務(wù)的公共字段聲明為該類型,使該SoapHeader在Web Services的公共合同中公開,并在創(chuàng)建代理時可由客戶端使用.
IssueVision的Web Services----IssueVisionServices.asmx如此實現(xiàn).
IssueVisionServices.asmx代碼片斷:
public class IssueVisionServices : WebService
{
...
private CredentialSoapHeader m_credentials;
// custom SOAP header to pass credentials
public CredentialSoapHeader Credentials
{
get { return m_credentials; }
set { m_credentials = value; }
}
.......
}
3. 在Web Services使用 SoapHeader 自定義屬性定義一組關(guān)聯(lián)的標頭,服務(wù)中的每個 WebMethod 都可以使用.(默認情況下,標頭是必需的,但也可以定義可選標頭)
IssueVisionServices.asmx代碼片斷:
....
[WebMethod(Description="Returns the lookup tables for IssueVision.")]
[SoapHeader("Credentials")]
public IVDataSet GetLookupTables()
{
SecurityHelper.VerifyCredentials(this);
return new IVData().GetLookupTables();
}
SecurityHelper類的VerifyCredentials方法用來從Web Services中的SoapHeader類來得到自定義身份驗證憑據(jù)(如用戶名和密碼).
SecurityHelper.cs代碼片斷如下:
// verifies the clients credentials
public static void VerifyCredentials(IssueVisionServices service)
{
if (service.Credentials == null service.Credentials.Username == null service.Credentials.Password == null ) //如果沒有認證信息,返回SoapException,這樣就不能匿名調(diào)用Web Method了
{
EventLogHelper.LogFailureAudit("A login was attempted with missing credential information.");
throw new SoapException(string.Empty, SoapException.ClientFaultCode, "Security");
}
string password = Authenticate(service.Credentials);
}
// authenticates a user's credentials passed in a custom SOAP header
private static string Authenticate( CredentialSoapHeader header)
{
DataSet dataSet = new DataSet();
string dbPasswordHash;
try
{
SqlConnection conn = new SqlConnection(Common.ConnectionString);
SqlCommand cmd = new SqlCommand("GetUser", conn);
cmd.Parameters.Add("@UserName", header.Username);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dataSet);
}
catch (Exception ex)
{
EventLogHelper.LogFailureAudit(string.Format("The GetUser stored procedure encounted a problem: {0}", ex.ToString()));
throw new SoapException(string.Empty, SoapException.ServerFaultCode, "Database");
}
// does the user exist?
if (dataSet.Tables[0].Rows.Count == 0)
{
EventLogHelper.LogFailureAudit(string.Format("The username {0} does not exist.", header.Username));
throw new SoapException(string.Empty, SoapException.ClientFaultCode, "Security");
}
else
{
// we found the user, verify the password hash by compare the Salt + PasswordHash
DataRow dataRow = dataSet.Tables[0].Rows[0];
dbPasswordHash = (string)dataRow["PasswordHash"];
string dbPasswordSalt = (string)dataRow["PasswordSalt"];
// create a hash based on the user's salt and the input password
string passwordHash = HashString(dbPasswordSalt + header.Password);
// does the computed hash match the database hash?
if (string.Compare(dbPasswordHash, passwordHash) != 0)
{
EventLogHelper.LogFailureAudit(string.Format("The password for the username {0} was incorrect.", header.Username));
throw new SoapException(string.Empty, SoapException.ClientFaultCode, "Security");
}
}
return dbPasswordHash;
}
4. 最后客戶端在調(diào)用要求標頭的方法之前,需直接在代理類上設(shè)置標頭.
IssueVision 的SmartClient端的WebServicesLayer類來調(diào)用此Web Services
WebServicesLayer.cs程序片斷如下:
private static IssueVisionServices GetWebServiceReference(string username, string password)
{
IssueVisionServices dataService = new IssueVisionServices();
//<ReplaceWithWse>
CredentialSoapHeader header = new CredentialSoapHeader();
header.Username = username;
header.Password = password;
dataService.CredentialSoapHeaderValue = header;
//</ReplaceWithWse>
InitWebServiceProxy(dataService);
return dataService;
}
通過以上步驟就可以完成Web Services自定義身份驗證了.IssueVision中還有很多相關(guān)的操作,因為在這里只是討論一下SoapHeader的用法,就不在列舉了.
鄙人見識就這么多了,歡迎大家討論,提出新的看法.
CopyRight © YellowWee 2004. All Right Reserved.