代码改变世界

师姐框架设计,权限角色与认证 以及操作权限

2011-06-02 16:44  沐海  阅读(1155)  评论(5编辑  收藏  举报

先说一句:师姐把框架搭起来后。每个后台只要简单的加上对应的引用。就可以自动实现权限判断。不需要再去修改源程序。

另外:师姐忙毕业的事情,已经不再带我了。而我还是个菜鸟。请各位多多指教。

认证和授权误入迷途

我原本想。

  Security.UserPrincipal newUser = Security.UserPrincipal.ValidateLogin(userName, password);

                //把生成的用户对象放入Context.User,这样做将会把完整的用户信息加载到ASP.NET提供的验证体系中

   Context.User = newUser;

   FormsAuthentication.SetAuthCookie(userName, false);

这样只能保证 其他页面中Context.User能取出用户名来。其他的根本没有用了。只是做一次密码验证和角色验证吗?

一直在困惑。现在才明白。又进入牛角尖了。师姐说过:你一直在用一个没解决的方法去解决问题。应该换个角度。

这次我不再跟踪代码。

我利用URL直接进入其他页面。发现根本没有进入PAGE_LOAD里面的具体操作就直接返回一个“没有权限”了。

于是,才想到,师姐一直说“基页”“基页”的方式。

然后再找到真正的破解方式.

师姐谈过的 认证和授权的使用方式如下

1. 让所有的页面都继承自基页。

 

namespace Web.Opanel.UpdatePassword

{

    public partial class UpdatePassword : Security.BasePage

{

让所有的页面都继承自基页。

2.这里利用了三个类来做的权限

BasePage.cs//基页  功能:继承此基页的WEB页面加载之前用此基页的方法 来做权限验证操作;引用//UserPrincipal.cs的对象实例来进行权限操作和读取判断。

UserPrincipal.cs(授权)//基页中使用,功能:根据用户名(验证用户名)来得到 权限,角色。并引                  //用UserIdentity.cs创建其对象实例来得到验证信息

UserIdentity.cs(验证)//得到用户名,进行验证,并标注是否验证、验证密码。

这里引出一个问题。

BasePage中对具体权限和验证的方法所需要的对象是从哪里读取的问题?

读取有两种方式:SESSION 和 Context.User

而对于的,这两种方式都要求在登录的后台中 进行存入。

如果使用Session存储用户信息。

(登录时)

Session["UserInfo"] = currentUser;//把对象信息放入session中

(BasePage中)

if ((Session["UserInfo"] == null))

                {

                    FormsAuthentication.SignOut();

                    Session.Clear();

                    Session.Abandon();

                    Response.Clear();

                    Response.Write("<script defer>window.alert('您没有权限进入本页或当前登录用户已过期!\\n请重新登录或与管理员联系!');parent.location='" + Common.ServerInfo.GetRootURI() + "Login/Login.aspx';</script>");

                    Response.End();

                }

如果使用Context.User存储信息。

这里牵扯到一个FORM验证

(登录时)

  FormsAuthentication.SetAuthCookie(userName, false);

单独只写一个FORM验证。使用Context.User.Identity.Name就可以得到数据。

因为。CONTEXT是HTTP.CONTEXT。Context.User.Identity是.NET中System.Security.Principal.Iprincipal. IIdentity Identity不是你自己定义的Identity对象。

(BasePage)if (!Context.User.Identity.IsAuthenticated)

                {

                    FormsAuthentication.SignOut();

                    Session.Clear();

                    Session.Abandon();

                    Response.Clear();

                    Response.Write("<script defer>window.alert('您没有权限进入本页或当前登录用户已过期!\\n请重新登录或与管理员联系!');parent.location='" + Common.ServerInfo.GetRootURI() + "/Opanel/Login/Login.aspx';</script>");

                    Response.End();

                }

当然。这里并不是说SESSION用了。FormsAuthentication验证就不能用了。你完全可以同时用这两种方式来结合进行存储。但FORM验证中有时间限制,这里建议用SESSION存储(也有时间限制)。因为Session存储的比较多(MODEL)。FORM验证也可以存大量数据。必须自己去重写:参考:http://www.tracefact.net/Asp-Net/FormsAuthentication.aspx

上面只是比较简单的一种验证和角色

————————————————

下面有一个针对每个角色以及其增删改查权限的设计。

使用时:

OperationType operationType = (OperationType)Enum.Parse(typeof(OperationType), Request["operationType"].ToString());//操作类型

Command.AdminInfo.Receiver receiver = new Command.AdminInfo.User(Context.User.Identity.Name.ToString(), operationType.GetHashCode().ToString());

----第一句

『public User(string _username, int _PermissionID)

        {

            this.username = _username;//用户名

            this.PermissionID = _PermissionID;//权限的CODE

            //this.operationType = _PermissionID;

        }

public User(string _username, string _operationType)

        {

            this.username = _username;

 

            this.operationType = _operationType;

            queryOperation = QueryOperation();

            addOperation = AddOperation();

            deleteOperation = DeleteOperation();

            updateOperation = UpdateOperation();

        }

 

 

 

                Command.AdminInfo.Command command = new Command.AdminInfo.Operation(receiver);

『此方法里有一个public override void execute()

        {

            this.receiver.Operation();//其实就是USER中的方法,验证是否有权限

            //throw new NotImplementedException();

        }』

 

                Command.AdminInfo.Invoker invoker = new Command.AdminInfo.Invoker();

『private List<Command> command=new List<Command>();

        public void setCommand(Command _command)

        {

            //this.command = _command;

            command.Add(_command);//多个权限的《receiver》LIST集合。(每个权限都是一个对象)

        }

        public void action()

        {

            foreach (Command cmd in command)

            {

                cmd.execute();//执行USER的执行  遍历判断是否有权限

            }

            //this.command.execute();

        }』

                invoker.setCommand(command);//把最新的操作放进去

 

                invoker.action();//执行。

如果在你操作时。USER判定你没有此操作权限则

            if (!TestOperation())

            {

                string st = string.Empty;

                st = "{result:'您没有权限执行此操作!'}";

                HttpContext.Current.Response.Write(st);

                HttpContext.Current.Response.Flush();

                HttpContext.Current.Response.End();//当前的输出将被打断。即其他的程序也不会再进行了。

            }

v』

所以。只要把以上这些代码放入 PAGE——LoaD 中的最开头就可以了。不需要担心下面的方法是否执行。

要注意:使用此的类时。如果不是增删改查的话。就会被默认为有权限

『/// </summary>

        protected bool TestOperation()

        {

            bool OPermission = true;

            switch (operationType)

            {

                case "1"://查询权限

                    if (queryOperation == "0")

                    {

                        OPermission = false;

                    }

                    break;

                case "2"://插入权限

                    if (addOperation == "0")

                    {

                        OPermission = false;

                    }

                    break;

                case "3"://删除权限

                    if (deleteOperation == "0")

                    {

                        OPermission = false;

                    }

                    break;

                case "4"://修改权限

                    if (updateOperation == "0")

                    {

                        OPermission = false;

                    }

                    break;

                default:

                    break;

            }

            return OPermission;

        }』

学习经历:

  1. 对不钻牛角的学习方式 感觉豁然开朗
  2. 对于微软.NET中的接口终于有了认识。就像:.Iprincipal. Iidentity这些接口。其实他们只是借口。重要的是。我们继承接口进行我们想要的开发。
  3. 要多看,多想才能明白
  4. 为什么我们对.NET或JAVA内部的类不认识。因为我们看不到其中的代码怎么写的。只是硬性的记忆它的功能,而不知道,它内部怎么执行的。就好象以上中,为什么必须放在头部?为什么其他类型就可以(  HttpContext.Current.Response.End();和默认初始 为 TRUE。只有没有增删改查这四个权限时才为FALSE.其他权限的默认为TRUE)
  5. 这里师姐写这个工厂模式的类,让我感觉很有点站在架构上写代码的感觉了。

向师姐学习。因为看这样的代码是一种享受。加油。设计框架的时候,面向对象的思想才得到真正的体现。例如,接口,继承,多态。以前只是知道。现在看完师姐的框架终于明白他们为什么要出现。为什么有的程序员牛。有的不行。加油。

还有各位不要向上次那么无聊,多讨论技术。欢迎大家交流、指教。我是一个成长中的菜鸟。

记录生活、工作、学习点滴!
E-Mail:mahaisong@hotmail.com 欢迎大家讨论。
沐海博客园,我有一颗,卓越的心!