2008-09-24 40 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方法。