2008-09-24 75 views
7

這是情況。我有一個webservice(C#2.0),它由(主要)從System.Web.Services.WebService繼承的類組成。它包含幾個方法,都需要調用一個方法來檢查它們是否被授權。在每個web服務調用之前調用某種方法

基本上是這樣的(原諒架構,這純粹是作爲示例):

public class ProductService : WebService 
{ 
    public AuthHeader AuthenticationHeader; 

    [WebMethod(Description="Returns true")] 
    [SoapHeader("AuthenticationHeader")]   
    public bool MethodWhichReturnsTrue() 
    { 
     if(Validate(AuthenticationHeader)) 
     { 
      throw new SecurityException("Access Denied"); 
     } 
     return true; 
    } 

    [WebMethod(Description="Returns false")] 
    [SoapHeader("AuthenticationHeader")]   
    public bool MethodWhichReturnsFalse() 
    { 
     if(Validate(AuthenticationHeader)) 
     { 
      throw new SecurityException("Access Denied"); 
     } 
     return false; 
    } 

    private bool Validate(AuthHeader authHeader) 
    { 
     return authHeader.Username == "gooduser" && authHeader.Password == "goodpassword"; 
    } 
} 

正如你可以看到,Validate有方法中每個方法調用。我正在尋找一種方法來調用該方法,同時仍然能夠以一種理智的方式訪問肥皂標題。我查看了global.asax中的事件,但我認爲我不能訪問該課程中的標題...我可以嗎?

回答

9

下面是你需要做的,以使其正常工作。

它可以創建自己的自定義SOAPHEADER:

public class ServiceAuthHeader : SoapHeader 
{ 
    public string SiteKey; 
    public string Password; 

    public ServiceAuthHeader() {} 
} 

然後,你需要一個SoapExtensionAttribute:

public class AuthenticationSoapExtensionAttribute : SoapExtensionAttribute 
{ 
    private int priority; 

    public AuthenticationSoapExtensionAttribute() 
    { 
    } 

    public override Type ExtensionType 
    { 
     get 
     { 
      return typeof(AuthenticationSoapExtension); 
     } 
    } 

    public override int Priority 
    { 
     get 
     { 
      return priority; 
     } 
     set 
     { 
      priority = value; 
     } 
    } 
} 

和一個自定義的SoapExtension:

public class AuthenticationSoapExtension : SoapExtension 
{ 
    private ServiceAuthHeader authHeader; 

    public AuthenticationSoapExtension() 
    { 
    } 

    public override object GetInitializer(Type serviceType) 
    { 
     return null; 
    } 

    public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute) 
    { 
     return null; 
    } 

    public override void Initialize(object initializer) 
    {   
    } 

    public override void ProcessMessage(SoapMessage message) 
    { 
     if (message.Stage == SoapMessageStage.AfterDeserialize) 
     { 
      foreach (SoapHeader header in message.Headers) 
      { 
       if (header is ServiceAuthHeader) 
       { 
        authHeader = (ServiceAuthHeader)header; 

        if(authHeader.Password == TheCorrectUserPassword) 
        { 
         return; //confirmed 
        } 
       } 
      } 

      throw new SoapException("Unauthorized", SoapException.ClientFaultCode); 
     } 
    } 
} 

然後,在你web服務將以下標題添加到您的方法中:

public ServiceAuthHeader AuthenticationSoapHeader; 

[WebMethod] 
[SoapHeader("AuthenticationSoapHeader")] 
[AuthenticationSoapExtension] 
public string GetSomeStuffFromTheCloud(string IdOfWhatYouWant) 
{ 
    return WhatYouWant; 
} 

當你消費這個服務,你必須實例化自定義頁眉與正確的價值觀,並將其附加請求:

private ServiceAuthHeader header; 
private PublicService ps; 

header = new ServiceAuthHeader(); 
header.SiteKey = "Thekey"; 
header.Password = "Thepassword"; 
ps.ServiceAuthHeaderValue = header; 

string WhatYouWant = ps.GetSomeStuffFromTheCloud(SomeId); 
+0

並不像我想象的那麼直截了當。現在就試試這個。 – 2008-09-25 08:58:35

1

您可以通過從SoapExtension base派生類來實現所謂的SOAP擴展。這樣您就可以在調用特定的Web方法之前檢查傳入的SOAP消息並執行驗證邏輯。

1

我想看看增加了安全性方面的方法你正在尋找安全。看看PostSharp,特別是OnMethodBoundryAspect類型和OnEntry方法。