情况是这样的。我有一个 web 服务 (C# 2.0),它(主要)由一个继承自 System.Web.Services.WebService 的类组成。它包含一些方法,这些方法都需要调用一个方法来检查它们是否被授权。
基本上是这样的(请原谅架构,这纯粹是一个例子):
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
。我正在寻找一种能够调用该方法的方法,同时仍然能够以理智的方式访问 soap header 。我查看了 global.asax
中的事件,但我认为我无法访问该类中的 header ...可以吗?
最佳答案
要使其正常工作,您需要执行以下操作。
可以创建您自己的自定义 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);
}
}
}
然后,在您的网络服务中将以下 header 添加到您的方法中:
public ServiceAuthHeader AuthenticationSoapHeader;
[WebMethod]
[SoapHeader("AuthenticationSoapHeader")]
[AuthenticationSoapExtension]
public string GetSomeStuffFromTheCloud(string IdOfWhatYouWant)
{
return WhatYouWant;
}
当您使用此服务时,您必须使用正确的值实例化自定义 header 并将其附加到请求中:
private ServiceAuthHeader header;
private PublicService ps;
header = new ServiceAuthHeader();
header.SiteKey = "Thekey";
header.Password = "Thepassword";
ps.ServiceAuthHeaderValue = header;
string WhatYouWant = ps.GetSomeStuffFromTheCloud(SomeId);
关于c# - 在每次webservice调用之前调用某个方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/130427/