代码改变世界

总结两种WebService中身份验证的方法

2011-03-01 18:16  Jeff Chow  阅读(1047)  评论(0编辑  收藏  举报

方法一:通过SoapHeader进行身份验证

本人在网上看到该方法以后,觉得其不过为自己写的Service增加了一属性,该属性用于身份验证。为何该属性一定要是SoapHeader的子类呢?对于自定义的WebService(System.Web.Services.WebService的子类),被其他程序引用的时候,引用的程序也是无法访问它的public属性的,仅允许访问标记为WebMethod的函数。

 

这里提下另外一个问题,在网上看到有人问,自定义的WebService拥有属性P,并将P的Get和Set函数声明为WebMethod,调用了P的Set函数以后,再调用Get函数,发现P属性的的值没有被改变。下面回帖的答案说,这是由于Web模型是一个Request/Response模型,因此基于Web模型的WebService会在每次请求单独构造对像,也就是说调用Get和Set函数的是两个不同的对象。

 

对于不能访问自定义的WebService的属性的情况,SoapHerder似乎可以解决,这也是为什么那么多帖子介绍用SoapHeader来做身份验证的原因吧。如果自定义WebService中的属性属于SoapHeader或者是SoapHeader的子类,并且某一WebMethod带有SoapHeader(属性名)声明的话,引用的程序则可以访问该属性,属性名为<类型名>+Value。

比如我定义了继承SoapHeader的类MySoapHeader,

public class MySoapHeader : SoapHeader
{

}

然后我我自定义的属性中定义属于MySoapHeader的属性Header,

public class Service1 : System.Web.Services.WebService
{
    public MySoapHeader Header;   

}

再在WebMethod中加上SoapHeader声明,

[WebMethod]
[SoapHeader("Header")]
public string HelloWorld()
{
    return  string.Empty;
}

那么,引用程序则可以通过Service1的MySoapHeaderValue属性来获取或者设置Header属性。并且在new了Service1的对象,对MySoapHeaderValue属性进行修改以后,还能访问到修改以后的值。而Service1的其他成员函数,弱需要访问Header属性,同样需要SoapHeader("Header")声明。我想,这就是为什么使用SoapHeader进行身份验证的原因吧。

 

方法二:Windows身份验证

 

这种方法,源于IIS中禁用了匿名访问(可以是网站范围,也可以是虚拟目录范围),引用程序可以通过WebService从System.Web.Services.Protocols.WebClientProtocol继承来的Credentials属性获取或者设置(实例化System.NetNetworkCredential对象)验证凭据。

 

对比

对于第一种方法,显然在实际的项目中,它能为我们提供更好的身份验证方式,比如说根据传来的用户名和密码与数据库中的用户相匹配。但问题是在SoapHeader中传用户名和密码应该还是有安全问题,需要进行加密。而方法二,如果仅仅是公司内部或者用户角色复杂度不高的应用,还是非常方便的。而如果整个WebService项目涉及很多不同用户不同级别的访问,则服务器的部署工作将会非常巨大。