使用SoapHeader传递Web Serivices自定义的身份验证数据

本文介绍如何使用SoapHeader进行WebServices的身份验证。通过创建自定义的SoapHeader类,可以在WebServices方法中传递认证信息,如用户名和密码,并在客户端调用时设置这些信息。
在调用Web Serivices,往往需要身份验证,使得通过验证的用户才能调用你Web Serivices中的方法.当然你可以通过将参数添加到每个需要自定义身份验证方案的Web services方法中去,这需要花费很大的精力.IssueVision 中使用了非常常用而且有效便捷的方法-----使用SoapHeader来实现自定义身份验证数据的传递.
    
SoapHeader提供了一种方法,用于将数据传递到Web services方法或从Web services方法传递数据,条件是该数据不直接与Web services 方法的主功能相关. 你不用将参数添加到每个需要自定义身份验证方案的Web services 方法,而可以将引用从SoapHeader派生的类的 SoapHeaderAttribute 应用于每个Web services 方法。从SoapHeader派生的类的实现处理该自定义身份验证方案. IssueVision 就是利用SoapHeader的这种能力来实现自定义身份验证数据传递的.

    
我们来看一下如何利用SoapHeader来传递数据.
     1. 首先需要在服务中定义一个从 SOAPHeader 派生的类,表示传入 SOAP 标头的数据.
    IssueVision
在中IssueVisionWeb项目(此项目用于发布Web Services)中通过创建CredentialSoapHeader类来实现第一步.

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. 将服务的公共字段声明为该类型,使该SoapHeaderWeb Services的公共合同中公开,并在创建代理时可由客户端使用.

    IssueVision
Web Services----IssueVisionServices.asmx如此实现.

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 自定义属性定义一组关联的标头,服务中的每个 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类来得到自定义身份验证凭据(如用户名和密码).

  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,这样就不能匿名调用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. 最后客户端在调用要求标头的方法之前,需直接在代理类上设置标头.

  IssueVision
SmartClient端的WebServicesLayer类来调用此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中还有很多相关的操作,因为在这里只是讨论一下SoapHeader的用法 
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值