有鹏友在如鹏网的QQ群中提了一个问题:
请问,在ASP.Net中如何隐藏一个MenuItem,我想根据不同的权限,对功能菜单进行隐藏,用style不行。
如果要仅仅解答这个问题,很好解答,答案很简单:
给MenuItem设定Value,然后用从根节点开始的MenuItem父子关系构成的ValuePath路径FindItem,然后把它从父节点中Remove掉即可。如下
<asp:Menu ID="Menu1" runat="server"> <Items> <asp:MenuItem Text="系统管理" Value="SysMgr" > <asp:MenuItem Text="用户管理" Value="UserMgr"></asp:MenuItem> <asp:MenuItem Text="配置管理" Value="ConfigMgr" ></asp:MenuItem> </asp:MenuItem> <asp:MenuItem Text="新建项" Value="新建项"></asp:MenuItem> </Items> </asp:Menu> MenuItem mi = Menu1.FindItem("SysMgr/ConfigMgr"); if (mi != null) { mi.Parent.ChildItems.Remove(mi); }
如果只是简单的分享一下这个问题的话,我就没必要写一篇博客了,我想接下来分享三个问题:
1)为什么这种“隐藏菜单”的方案非常不安全;
2)为什么说ASP.net WebForm是个坑;
3)为什么ASP.Net MVC应用越来越广;
不少网站系统开发的时候是这样做权限控制的:如果当前用户没有这个菜单的执行权限,就把菜单隐藏起来,认为这样就“安全”了。但是Http协议是开放的,访问者可以采用直接在地址栏输入“没有权限访问”的页面的地址或者制造一个模拟执行被隐藏菜单的Http请求,这样就可以轻松的访问“没有权限访问”的页面了。
类似的安全漏洞还有:
1)把用户不可以看的数据在列表中隐藏掉,岂不知用户可以直接拼凑url访问其他数据或者删除它不能删除的数据;
2)做手机号验证的时候把被验证的手机号写到隐藏字段中,岂不知这样用户就可以先用一个真实的手机号请求验证码,在验证环节再修改隐藏字段中的手机号为一个假手机号,这样一个假手机号进行认证了
3)普通访问者通过http://www.rupeng.com/UserInfo/36这样的url可以看到自己的个人信息,如果不做控制的话,恶意访问者就可以用http://www.rupeng.com/UserInfo/1、http://www.rupeng.com/UserInfo/2、http://www.rupeng.com/UserInfo/3……这样的方式一个个的把你的注册用户的信息全部“拖库”下来。
如此等等……
正确的做法是:
1)没有权限看的数据不仅要隐藏,还要在 “看数据”的页面中进行“二次查岗” ,再次检查当前用户是否有查看权限;
2)把这些客户端篡改后就会对安全性有威胁的数据放到服务器端Session中;
不仅B/S系统有这样的安全漏洞,很多C/S系统这样的漏洞更多,我看到过很多C/S系统是客户端直连数据库,稍微懂一点编程的人可以直接访问数据库“为所欲为”。正确的做法应该是使用WCF等技术开发一个中间层,把业务逻辑、权限控制等写到中间层,数据库访问等操作都在中间层完成,对外暴露接口,客户端程序去访问中间层接口,并不直接访问数据库。
对于有一定经验的开发者来讲,这点大家应该都清楚,我在这里就不再多说,如果有鹏友不清楚这一点的,可以在评论中继续交流。
对我有一些了解的朋友会知道,这几年我一直在.Net技术圈倡导一个理念“不做只会拖ASP.Net WebForm控件的菜鸟”,不知道和我这点努力是不是有关系, 目前国内重度使用ASP.Net WebForm的公司越来越少,更多的公司开始轻量级的使用ASP.net WebForm或者直接干脆转向使用ASP.net MVC 。
当然并不是说“ASP.net WebForm不好”,因为照样有很多不错的系统是使用ASP.net WebForm开发出来的,我这里想说的是“ASP.net WebForm容易被误用”,说的严重点“ ASP.Net很容易诱导犯罪 ”。
就像如果你选择了一个大美女跟你共处一室,你做了顺从内心但是违反了法律的事情,这不是大美女的责任,你不能谴责“谁让她穿的那么暴露,都是她的责任”,是你的错就要你来承担。如果你当初选择跟凤姐共处一室,我相信你更多的是跟她讨论《故事会》、《知音》等古典文学话题。
同理,有人能把ASP.Net WebForm用的“坐怀不乱”,但更多的人用ASP.Net WebForm的时候容易“日后再说” 。那么ASP.Net WebForm有哪些诱导大家犯罪的地方呢?
ASP.net WebForm设计的初衷就是微软想复制VB、WinForm等技术的成功路线。
如果直接使用Win32 API进行Windows程序开发,你需要面对消息循环、消息机制、结构体、句柄等等各种复杂的问题,而使用VB、WinForm等技术,只要明白“控件、属性、方法、事件”这几个概念,就可以拖拖拽拽的开发一个系统出来。
同样的,进行Web开发的时候程序员也需要理解Http协议、Cookie等细节的复杂东西,微软想用WebForm这样一种类似WinForm的拖控件的傻瓜化开发方式把程序员再次解放出来。但是事与愿违,Web系统的安全性、效率等的要求决定了“把开发人员变傻瓜化”这样一条路是走不通的, Web程序员必须明确的知道生成的每一个html字符的意义、浏览器和服务器之间的通讯细节,才能开发出安全、高效的Web系统出来。
而ASP.net WebForm把底层东西都封装好了,html的生成、请求的处理都是在内部神奇的偷偷完成的。对于不求甚解的初学者,秉承着“能实现就行”的心态,用ASP.net WebForm的这些神奇的控件开发出了速度缓慢、漏洞百出的系统。而且由于不知道ASP.net WebForm是怎么生成那样一坨坨的html代码以及怎么样处理我们的请求的,所以一旦遇到问题,就只能去社区中 “求大牛赐予我一个神奇的控件”、“求大牛赐予我一段神奇的代码可以神奇的解决我神奇的问题” 。对于想精确的控制生成的Html、精确的控制请求处理过程的程序员来讲,ASP.net WebForm就又有点自作聪明的帮我们做很多事情,束手束脚,有时候这些控件太智能,也会让高手一不留神犯错。
如果是开发一个简单的、安全性要求不高的Web系统,ASP.net WebForm也能快速开发出来满足要求了,但是如果要想开发复杂的、访问量比较大的、对安全性很重视的Web系统,一定要谨慎,尽量不重度用ASP.net WebForm,要么只是把aspx当成模板引擎用,要么就像如鹏网一样使用ASP.net MVC来进行开发。
为什么ASP.Net MVC应用越来越广
上面我提到了Web开发者必须有能力对“请求、处理、响应”的整个过程进行控制,必须明白生成的Html是什么回事、必须明白每个请求是怎么发出去的,很显然ASP.Net WebForm这条路走错了。而Struts、ROR等这些轻量级的框架则发展越来越好(当然也不知道Sun公司哪根筋抽了,竟然在本来已经很好的Java世界中搞了一个模仿WebForm的JSF框架出来,还把它搞成了Java标准,无奈乎没人Diao这个标准库。这就是传说的“倒行逆施”吧。)
因此开源世界开始制造ASP.net的第三方MVC框架,比如移植自Struts的NStruts;我在如鹏网在线编程训练营的.Net培训课程中也用“HttpHandler+Razor模板引擎”搭建了一个MVC框架;刚刚还模仿Java中的“Servlet+RequestDispatcher+JSP”MVC做法搞了一个只用asp.net webform、 完全不用第三方库的“HttpHandler+Server.Transfer+aspx”MVC框架 ,很有意思,稍后我会在我的微信朋友圈写文章分享一下这个大家一眼就可以看懂、同时又“很MVC”的框架。我的微信号是:yzk369
不过微软社区的特点是“大家都不信任第三方框架,只有微软官方出的大家才用”,所以NStruts之类的都没有得到广泛应用。还好微软公司及早认识到了这一点,研发出了集Struts、ROR等优点于一身的ASP.Net MVC。业务代码和UI分离,程序员可以在View模板对生成的Html进行精细化的控制,Controller只管对客户端的请求进行处理,整个开发过程清晰明了。没有了讨厌的IsPostBack、没有了DataBind、没有了精神病似得OnDeleted和OnDeleting、没有了然并卵的“页面生命周期”……
请求→处理→响应,就是这么简洁!
不过,由于各种原因,目前还是有一些项目、一些开发人员在使用ASP.net MVC,我准备近期搞一次ASP.net MVC的免费网络公开课,给大家讲一讲。为了公开课能更好的满足大家的需求,我设计了一个调查问卷,收集一下大家的想法。公开课时间确定之后也会通知大家。调查问卷的地址: https://www.wenjuan.com/s/m67fq2/