WebService安全性的几种实现方法【身份识别】

相信很多开发者都用过WebService来实现程序的面向服务,本文主要介绍WebService的身份识别实现方式,当然本文会提供一个不是很完善的例子,权当抱砖引玉了.

首先我们来介绍webservice下的两种验证方式,

一.通过集成windows身份验证

通过集成windows方式解决webservice的安全问题是一个很简洁,并且行之有效的解决方案,该方案的优点是比较安全,性能较好,当然因为与windows紧密的结合到了一起,缺点自然也很明显了,第一,不便于移植,第二,要进行相关的配置部署工作(当然我们也可以用代码来操作IIS,只不过比较麻烦,最近一直做自动化部署,所以一讲到配置马上就会联想到怎么去自动部署)

具体怎么做呢?

服务器端:配置IIS虚拟目录为集成windows身份验证

客户端:

Service1 wr = new Service1(); //web service实例  

wr.Credentials = new NetworkCredential(“administrator”,”123″); //用户名密码  

lblTest.Text = wr.Add(2,2).ToString(); //调用Add的 web service方法 

二.使用 SoapHeader(SOAP 标头)自定义身份验证

SoapHeader 多数情况下用来传递用户身份验证信息,当然它的作用远不止如此,有待于在实际应用中发掘,体可以实现哪些东西大家有想法可以留言一起交流.

SoapHeader 使用步骤: 
(1) 创建继承自 System.Web.WebServices.SoapHeader 的自定义 SoapHeader 类型。 
(2) 在 WebService 中创建拥有 public 访问权限的自定义 SoapHeader 字段。 
(3) 在需要使用 SoapHeader 的 WebMethod 上添加 SoapHeaderAttribute 访问特性。SoapHeaderAttribute 构造必须指定 memberName 参数,就是我们在第二步中申明的字段名称。 
(4) 生成器会自动为客户端生成同名的自定义 SoapHeader 类型,只不过比起我们在 WebService 端创建的要复杂一些。同时还会为代理类型添加一个 soapheaderValue 属性。

下面展示一段SoapHeader的代码,多余的方法将会在后面用到

客户端

服务器端

当我们拥有很多个类的时候,要添加一个或者删除一个验证方式(假设需要进行多种认证)是非常麻烦的,我们不可能跑到每个方法里面去加一个方法调用,这是灾难性的工作,当然我们也可以用AOP来实现,Aop的话需要额外增加很多代码或者直接引入第三方来做,但是我们可不可以有更简便的方法呢?

OK,答案就是使用HttpModule,我们集成IHttpModule写一个处理模块,那么它的原理是什么呢?具体进行了哪些操作呢?我们的思路如下:

 

下面来看看我们的Module代码

 1 public class WebServiceAuthenticationModule : IHttpModule 2 { 3 private static WebServiceAuthenticationEventHandler 4 _eventHandler = null; 5 /// <summary> 6 /// 验证事件.绑定到此事件可进行对用户身份的识别 7 /// </summary> 8 public static event WebServiceAuthenticationEventHandler Authenticate 9 { 10 add { _eventHandler = value; } 11 remove { _eventHandler -= value; } 12 } 13 public Result Result = new Result(); 14 15 public void Dispose() 16 { 17 } 18 public void Init(HttpApplication app) 19 { 20 app.AuthenticateRequest = new 21 EventHandler(this.OnEnter); 22 Result.EndValid = new 23 EventHandler(this.OnCheckError); 24 } 25 26 /// <summary> 27 /// 验证用户身份 28 /// </summary> 29 /// <param name="e"></param> 30 private void OnAuthenticate(WebServiceAuthenticationEvent e) 31 { 32 if (_eventHandler == null) 33 return; 34 35 _eventHandler(this, e); 36 if (e.User != null) 37 e.Context.User = e.Principal; 38 } 39 40 public string ModuleName 41 { 42 get { return "WebServiceAuthentication"; } 43 } 44 45 void OnEnter(Object source, EventArgs eventArgs) 46 { 47 HttpApplication app = (HttpApplication)source; 48 HttpContext context = app.Context; 49 Stream HttpStream = context.Request.InputStream; 50 51 // Save the current position of stream. 52 long posStream = HttpStream.Position; 53 54 // If the request contains an HTTP_SOAPACTION 55 // header, look at this message.HTTP_SOAPACTION 56 if (context.Request.ServerVariables["HTTP_SOAPACTION"] == null) 57 return; 58 59 // Load the body of the HTTP message 60 // into an XML document. 61 XmlDocument dom = new XmlDocument(); 62 string soapUser; 63 string soapPassword; 64 65 try 66 { 67 dom.Load(HttpStream); 68 69 // Reset the stream position. 70 HttpStream.Position = posStream; 71 72 // Bind to the Authentication header. 73 soapUser = 74 dom.GetElementsByTagName("User").Item(0).InnerText; 75 soapPassword = 76 dom.GetElementsByTagName("Password").Item(0).InnerText; 77 } 78 catch (Exception e) 79 { 80 // Reset the position of stream. 81 HttpStream.Position = posStream; 82 83 // Throw a SOAP exception. 84 XmlQualifiedName name = new 85 XmlQualifiedName("Load"); 86 SoapException soapException = new SoapException( 87 "SOAP请求没有包含必须的身份识别信息", name, e); 88 throw soapException; 89 } 90 // 触发全局事件 91 OnAuthenticate(new WebServiceAuthenticationEvent 92 (context, soapUser, soapPassword)); 93 Result.OnEndValid(); 94 return; 95 } 96 void OnCheckError(Object sender, EventArgs e) 97 { 98 if (Result.BrokenRules.Count == 0) 99 { 100 return; 101 } 102 else 103 { 104 HttpApplication app = HttpContext.Current.ApplicationInstance; 105 app.CompleteRequest(); 106 app.Context.Response.Write(Result.Error); 107 } 108 } 109 }

Authenticate事件是一个静态的变量,这样我们可以在程序的外部来订阅和取消订阅事件(非静态的public 事件在外部也是不能进行订阅和取消订阅事件的,这也是事件和委托的一个区别之一)

下面是我们的事件参数以及委托

我们在Global.asax的Application_Start方法里面把前面介绍的静态方法ServiceCredential.CheckUser订阅到我们Authenticate事件上,前面提到的增加和删除多种认证方式就是通过这种方法实现的.

 

 protected void Application_Start(object sender, EventArgs e) { WebServiceAuthenticationModule.Authenticate += ServiceCredential.CheckUser; }

 

 

 

我们在ServiceCredential.ValideUser方法设置了返回false,这是针对测试的一个配置,实际情况下我们可以和数据库结合起来写一个认证 运行上面讲解SoapHeader的那段代码,你会发现我们的认证已经有效了.关于文章中用到的Result类改天在用一篇文章记录一下,这是一个非常好的记录错误的方案

原文链接:https://www.cnblogs.com/guyuehuanhuan/p/6851501.html

原创文章,作者:优速盾-小U,如若转载,请注明出处:https://www.cdnb.net/bbs/archives/18563

(0)
上一篇 2023年9月1日 01:36
下一篇 2023年9月1日 07:32

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

优速盾注册领取大礼包www.cdnb.net
/sitemap.xml