注册 登录
编程论坛 ASP.NET技术论坛

利用ASP.NET框架制作“模拟基于角色”的安全登陆

ilovetea 发布于 2008-11-24 14:42, 5505 次点击
利用框架制作“模拟基于角色”的安全登陆

我混在这里很长时间,没发表过什么,今天有时间,我也发点见解,可能对新手有用。

注意:我的许多想法是基于”铲铲版主发表的利用框架制作“模拟基于角色”的安全登陆“文章后的一些想法

看到许多人在这个问题里打转,前些日子我也有疑问,经过这几天的研究发现点问题,可能对新手有用,那就是我们可以用基于用户的安全登陆来模拟出基于角色的安全管理登陆,有偷工减料的嫌疑,但我觉得还是很好用的。高手就别看了,呵呵,不要扔砖头啊

正式开始:我用的是VS2005,数据库是SQL2005

首先建立一个用户的数据库A:"表A"

表A中有3列:用户名,密码,角色

数据先写2个吧:admin 123 管理员

                          user    123 普通用户

由于主要想写的是用户管理部分,所以数据库连接部分省略掉,大家自己也会,我就不废话了。

想实现的功能是:文件夹admin只允许管理员访问,文件夹user只允许普通用户使用

文件:
只有本站会员才能查看附件,请 登录



在根目录的WEB.CONFIG中写入:
只有本站会员才能查看附件,请 登录


意思是:启用Forms验证模式
只有本站会员才能查看附件,请 登录


在default.aspx中:


在default.aspx.cs中写入代码:

    protected void Button1_Click1(object sender, EventArgs e)
    {
        SqlConnection con = DB.GetCon();
        con.Open();
        string uname = this.TextBox1.Text;
        string upws = this.TextBox2.Text;
        string ujs = this.DropDownList1.SelectedValue.ToString();
        SqlCommand cmd = new SqlCommand("select userJs from admin_gl where userName='"+uname+"' and userPws='"+upws+"' and userJs='"+ujs+"'", con);
        string js = Convert.ToString(cmd.ExecuteScalar());
//验证用户是否存在并输出查询结果
        con.Close();
        if (js=="管理员")
        {
            System.Web.Security.FormsAuthentication.SetAuthCookie(js, false);
            Response.Redirect("~/admin/index.aspx");
        }
        else if (js=="普通用户")
        {
            System.Web.Security.FormsAuthentication.SetAuthCookie(js, false);
//*当确认用户验证是合法的,则调用System.Web.Security.FormsAuthentication.SetAuthCookie(userid, false)方法,发送验证Cookie,此方法传递两个参数,一个是代表用户的标示,一般来说,在接下来确认用户唯一身份的就是从数据库中获得的userid。第二个参数告诉.NET是否写入持续的Cookie,如果为true,则Cookie将被持续,下次用户再次访问时,Cookie仍存在(相当于记住用户,可以提供这样的复选框让用户来决定是否持续Cookie)。发送了Cookie后,即可调用跳转语句跳转到指定地方。*//

            Response.Redirect("~/user/index.aspx");                  
        }
        else
        {
            this.Label1.Text = "用户名或密码错误请重新输入";
            this.TextBox1.Text = "";
            this.TextBox2.Text = "";
        }
        
    }

这段代码中关键的地方在于蓝色字体部分,也是实现模拟角色管理的重要步骤

这里需要说的的,我查询的不是用户名,而是数据库里的角色列,但不是真正的角色,而是把这列当成用户名处理。也就是说,在系统里,表里的角色列就等同于用户名。

在需要验证的文件夹里建立一个web.config文件。并写入:

    <system.web>
      <authorization>
        <allow users="管理员" />  //允许管理员访问
        <deny users="*" />        //不允许其他所有用户包括匿名用户都不能访问
      </authorization>
    </system.web>

意思是这个文件夹,只允许“管理员”使用,其他用户无法读写,

这么做的意义在哪呢?意义在于你以后可以随时建立管理员或者普通用户,不需要修改代码,而原始的用户验证需要修改代码,而真正的角色管理还需要进行其他设置,而实际上,这么用已经能够满足我们一般系统的管理使用了。

希望能给大家带来启发,呵呵,别扔砖头啊,哈哈

就到这里吧,休息休息一会儿

[[it] 本帖最后由 ilovetea 于 2008-11-24 21:55 编辑 [/it]]
20 回复
#2
小仙2008-11-24 20:47
很不错的帖子。
#3
小仙2008-11-24 20:53
有几个问题,Response.Redirect("~/admin/index.aspx");
“~/”这样写法我见过很多次,不过一直没弄懂是什么意思。
第2个,你的兰色部分字体,也就是你说的重要部分也没能标显出来。
第3个,发帖时,最好要注意下代码注释,虽然配有讲解,但是关键的代码还是要标上注释,很多名称不常用读者也许不认得。
总的来说还是写的不错。
#4
ilovetea2008-11-24 21:48
~/表示虚拟目录的根目录,
其他2点是由于发帖经验不足,呵呵
我这就去改改
#5
ilovetea2008-11-25 11:02
看的人不少,回帖的人少
#6
lzme2008-11-25 12:45
嗯 不错
#7
浩天2008-11-25 12:57
不错哈
#8
浩天2008-11-25 12:58
问哈哦   ~/  和  \\ 有啥区别哦
#9
ilovetea2008-11-25 13:31
~/表示虚拟目录的根目录
\\没用过,不清楚啊
#10
铲铲2008-11-25 15:43
~/ 是中表示“应用程序根”的符号。应用程序根通常是指编译的网站中bin文件夹所在的那个目录,具体说来,可以是添加了应用程序的虚拟目录(虚拟目录上点右键——属性——虚拟目录选项卡——应用程序设置,单击创建按钮。创建了应用程序的虚拟目录的图标会变成齿轮状);可以是一个站点的根目录。这样的话,就和“/”开头的路径一样了。
含有~/的路径是必须经过服务器处理才能使用的,因此只有在控件中可以使用,某些处理路径的方法会自动转换为符合要求的路径,如this.Page.Response.Redirect(路径)。你也可以用this.ResolveUrl(string url)方法在你的代码中转换这种路径,以符合输出要求。

/表示从站点根目录访问,即便在虚拟目录中,该路径仍然从一个实体站点根开始。

./表示从当前路径开始的子目录
../表示从上一级路径开始起算
../../表示从上两级路径开始起算。
但要注意,IIS可能不允许这种父路径表示法,它会造成安全问题。(各位想想为什么?)

\\这是用在字符串内的,因为\是转义符前缀,例如,想在字符串中包含双引号,但双引号在代码中是字符串的边界,那么就要用\"来表示包含在字符串中的双引号。同理,要想在字符串中表示\,就要写成\\。(除了一种情况,在字符串开头用@强制要求不转换:如string a = @"abcuse")

//这是C风格语言中的单行注释
#11
ilovetea2008-11-25 19:25
版主就是版主,厉害
#12
小仙2008-11-25 19:45
一直没弄清楚\和/的区别
好象\是物理路径
/是网络路径,
那http://有是个什么用法捏。
#13
铲铲2008-11-25 21:50
你是否考虑过,如上,你将本该传递用户标识的地方改成了传递用户的角色,角色是可以多个用户持有的,在今后登陆以后执行和用户密切相关的操作时,你就无法区分到底是哪一个用户在执行操作。例如,一个用户想登录以后,修改自己的基本信息。这样,你就无法在后续操作中得到用户标识,当他想这么做的时候,你不得不重新询问用户:你是谁?
#14
ilovetea2008-11-26 13:56
铲铲版主说到点子上了,的确有这样的问题存在,

不过既然想偷工减料,就得付出代价了,我也很无奈。

有个问题请教铲铲版主:

你说用“户名登陆验证”和“角色登陆验证”在安全方面有什么区别吗?

那个更安全些?
#15
小枣2008-11-26 14:28
不错,顶
#16
铲铲2008-11-27 09:51
我认为,本身你所提出的思路就存在概念上的不合理。
我们所说的登陆啊之类之类,归结为一个安全概念,那就是访问控制。
访问控制需要有两个必备:1、系统必须明确知道用户是谁。2、系统必须明确知道,访问这个资源的用户是否有权利。
第一个,大家很容易理解,我们经常使用“用户名”+“密码”的方式来让系统获知用户是谁。因为密码是隐私数据,我们仅认为合法用户才持有。因此,当一个用户提供了用户名和正确的密码,系统就可以认为是用系统的用户是谁。这个过程叫验证用户。

第二个,系统知道用户是谁,还必须知道用户是否有访问某个资源的权利。这个过程叫授权。一个验证、一个授权,前者是证明用户是谁,后者是决定一个资源是否允许被用户访问。

角色、组等概念并非访问控制所必须的。因为你可以在一个资源上添加“访问控制列表”,在该表中明确指定每一个用户是否有权访问它的记录,当一个用户要访问时,通过查表以决定是否允许。但这样会造成“访问控制列表”过于庞大,当用户成千上万时,它的伸缩性、性能非常低下。并且,为每个资源维护用户的访问表,其维护量基本上等于用户数和资源数的乘积,相当庞大。
于是,思考是否引入一个中间环节,将用户和资源对应关系进行缓冲。这就是角色、或者组。随你怎么说,只要在一个项目中,这些概念的含义相同就行。我们对资源的授权并不针对用户,而是针对角色或者组。
我认为,用角色的概念更贴近现实生活。首先、一个人有可能担当多种角色:例如,一个老师,对于学生,他是老师的角色,对于学校,他是工作者的角色,对于家庭,他是父亲/母亲的角色,对于银行,他是业务办理者的角色。其次,一个角色可能有很多人在扮演,全世界不止一个教师,银行也不乏仅他一个业务办理者。
因此角色和用户是N对N的关系。
当然,用“组”这个概念同样可以,随你怎么说,这取决于你的设计。

所以,对于你的设计而言,违背了最初设计原则。如楼主所说偷工减料吧,这样付出的代价就是违背设计原则,导致信息不全。在我的基于角色的安全访问中,任何元素都是必须的,没有冗余。


高阶技巧:
美国国家标准协会倡导了RBAC(基于角色的访问控制Role-based Access Control)。他还指定了RBAC的三种标准,分别是RBAC0、RBAC1、RBAC2。其中RBAC0是最基本的角色访问控制标准。如同我所有帖子一样,他们都是RBAC0的,用户和角色这两个元素都是没有层次结构的(属于平面数据)。更复杂RBAC系统,用户和角色的组织形式是树状结构的,并且,对于访问控制元来说,还可区分“允许”“拒绝”“未指定”,对控制策略来说,可以分为“拒绝优先法”等等,对于用户和角色呈现的树状结构,还存在追溯权限和继承关系,权限怎么追溯、怎么继承、怎么叠加等,都是设计访问控制需要考虑的问题,还有就是这些追溯、继承算法是否满足性能要求。
#17
ilovetea2008-11-27 11:34
谢谢,学到点东西
#18
blueskyss2008-11-27 13:00
我以前也和楼主差不多了做法,真的是存在很多不合理性,因为我只有一个管理员,很好解决,
看了可爱的铲铲发的文章以后(其实以前也搞过.其实没有搞懂),感觉太大了,
铲铲,我在等你QQ,因为我还有一些东西想问你,我QQ是:84420676
#19
ilovetea2008-11-29 20:27
谢谢CHANCHAN版主的解释
#20
zhaoxiaoxiang2008-12-02 03:39
回复 楼主 ilovetea 的帖子
先顶再说。。。。。。。。。。。
#21
zhjesse2008-12-07 11:09
不错,学习一下
1