这是情况.我有一个webservice(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标头.我看过那里的事件global.asax
,但我认为我不能访问该课程中的标题......我可以吗?
以下是您需要做的才能使其正常工作.
可以创建自己的自定义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);