you can store the user access right in database table, and retreive the data in session during the login.

解决方案 »

  1.   

    我想知道的是HOW TO DO?
    我指login 成功以后,进入一个asp.net的页面,比如http://mysite/test.asp.net(webform),里面有3按钮bt_add,bt_update,bt_check,根据登陆用户的权限不同,如经理有这3个按纽的全部执行权限,而开单人员只有bt_add,bt_update的功能,不可以执行bt_check按纽。我想实现的功能呢,就是构建一个安全模块:
    1:可以取得各个页面中的按纽的name,text,按纽所在的页面(webform)的name放在database里面。2:给每个role或user,根据user权限级别高低,设置页面(webform)里面按纽可否执行,这些信息就存在database中3:应用执行时,已通过验证的user,根据usid从database取出对各个页面(webform)的按扭(操作)清单,放在全局缓存中。用户在页面对按扭执行时,就根据全局缓存中的操作清单,判断该用户对该按扭是否有权限执行。
    这样就实现了对按扭,也就是实现了操作上的授权安全。4:如果可能的话,对httpapplication对象处理 AuthorizeRequest 事件应用程序级 (global.asax) 或者Http Module (实现 IHttpModule),实现第3步中的“就根据全局缓存中的操作清单,判断该用户对该按扭是否有权限执行。”
    以上,就是我要实现的自定制Web授权。第1步和第3步是困难所在,望楼上的
    2位,以及各位同行,多多关照,出建议!
      

  2.   

    你可以寫動態頁面,在你從DB中取出user所能進行操作的button後,然後把他加到頁面上去.一點小建議.
      

  3.   

    用隐藏按钮的方式来实现比较好,速度快,同样可以达到预期的效果.首先把功能进行编码,然后在需要控制权限的页面中的page_load中判断出是否有查看,创建,更新,删除的权限,用switch来设置相应的按钮是否显示.这样就完全可以作到每一个叶面的权限控制.
      

  4.   

    to: xuechenglv(爱雪的沙漠)
     你的建议不错,我可以试一下。我想把授权做成一个模块,供全局调用,你有什么进一步的看法,比如对怎么样取得各个webform中的按扭的id,并将id
    存到database中?
      to:7102(feiyang) 
     你说的 “写動態頁面”具体是什么意思如果,按照.net里提供的form验证和并在web.congfig里面做url授权的话,对
    一个大系统来手,不大实用!各位,也可以谈谈你们所实现的asp.net系统中是如何实现验证和授权的呢??我的qq 10032532  msn: [email protected]
      

  5.   

    隐藏显示控件,并控制用户执行函数的操作
    或者利用web控件进行动态控件创建。反正你页面有的东西是一定的,所以不需要给很大的自由空间去创建控件。
    验证授权都是通过数据库来验证的,一般不会和系统用户结合
      

  6.   

    to blackwingZero(blackwing) : 
      这样的话,要在每个页面都要写代码了。并且如果用户也要求对页面 URL(WebFom)需要授权的话。那么怎么样将页面URL(Webform)和按钮的ID写到database中呢。(不该手工增加记录到database中吧)很感谢,大家的回复。继续交流吧!
      

  7.   

    对于权限控制,可以和数据库集成起来。
    将不同的用户分配不同的角色role,
    然后给与不同的权限。
    可以通过数据库表操作的权限来控制。
      

  8.   

    我的一点想法:在httpmodule中取得用户可操作的权限信息。然后为所有要操作权限的页面定义一个基类,基类中有那些操作动作的按钮的定义,在基类中根据httpmodule中获得的权限信息设定按钮的状态。当然每个页面也得写代码,就是继承这个基类
      

  9.   

    to kenfil(kenfil):
    我最初的想法也在httpmodule获得用户可操作的权限信息,这一步,我可以实现了。
       现在我的主要问题是:1:如何确定页面按扭在DB中的一个唯一标志。
    比如webfrom_1.aspx中有ID为bt_add,bt_del,bt_update按扭,而webfrom_2.aspx中有bt_add,bt_del,bt_update,,bt_cheched,bt_query按扭。
    这样的话,对于bt_add,bt_del,bt_update它们的在页面中的ID是一样的。所以我们在数据库中还要加
    webfrom_1.aspx.bt_add,和webfrom_2.aspx.bt_add,这样才可以区分2个bt_add。可是我们这 样将这样的记录加到db中呢,手工一定不大好的吧。
    2:在页面中如何判断用户对按扭比如bt_add是否有执行的权限。也就是你如何实现“在基类中根据httpmodule中获得的权限信息设定按钮的状态”希望,你可以帮忙,非常感谢你的回复!
      

  10.   

    问题是你到底想做多自由?方法应该是根据情况定的.
    把控件放到数据库,让程序自动来控制生成这样自太复杂,不如传统的直接建立控件更为方便.
    如果要控制url只需要增加一个身份导向页面吗.
    你要更自由的那就把html代码直接存到数据库中!不过这样子人家微软开发控件干什么?
      

  11.   

    控制页面级的控件是不是比较麻烦呢?我一般是通过url来控制,比如a.aspx?view=all则提供所有可使用控件(提供本页面的所有功能),如果是a.aspx?view=show则只有显示功能等等,可能为不同的岗位分配不同的叶面(事实上还是同一个页面,只是不同的岗位看到不同的内容而已),最后还可以根据个人来微调,也就是说同一个岗位的人也可以拥有不同的权限
      

  12.   

    做一个Security.cs继承Page类,其中Page_Load的时候验证用户是否有权限访问一个url,可以通过继承Security类的叶面传递进去,在子类中调用base.Page_Load(sender,e)来验证,不过这种方法有一个不好的地方,权限虽然控制到了,但是如果页面在操作过程中需要传递特殊的参数的话,可能会出现没有权限访问的错误,具体问题还得具体解决了
      

  13.   

    to blackwingZero(blackwing) :
    你误解了我的意思。我意思是,取得页面中的按扭控件的ID,存到数据库中!  to mmkk:
     "可能为不同的岗位分配不同的叶面(事实上还是同一个页面,只是不同的岗位看到不同的内容而已),最后还可以根据个人来微调,也就是说同一个岗位的人也可以拥有不同的权限"
      能否具体点,怎么样处理。另外,你处理控制URL的时候,URL的名称怎么样
    如何增加到数据库中呢
      

  14.   

    我是一个新手,刚刚看到这个问题,比较感兴趣,我觉得可以这么做,如果你要控制权限的控件只是一个按钮,那么你可以继承.net的按钮类,自己写一个带验证权限的按钮类不可以嘛?
      

  15.   

    把我的问题,不要简单化。请细看我的问题!我想实现的功能呢,就是构建一个安全模块:
    1:可以取得各个页面中的按纽的name,text,按纽所在的页面(webform)的name放在database里面。2:给每个role或user,根据user权限级别高低,设置页面(webform)里面按纽可否执行,这些信息就存在database中3:应用执行时,已通过验证的user,根据usid从database取出对各个页面(webform)的按扭(操作)清单,放在全局缓存中。用户在页面对按扭执行时,就根据全局缓存中的操作清单,判断该用户对该按扭是否有权限执行。
    这样就实现了对按扭,也就是实现了操作上的授权安全。4:如果可能的话,对httpapplication对象处理 AuthorizeRequest 事件应用程序级 (global.asax) 或者Http Module (实现 IHttpModule),实现第3步中的“就根据全局缓存中的操作清单,判断该用户对该按扭是否有权限执行。”
      

  16.   

    做一个页面验证类,继承System.ui.web.page
    然后让需要身份验证的页面继承这个类
    在页面上放一个隐藏控件存储身份验证信息(可以自己做一个dll)
    然后再session或者页面参数里传递用户名和模块名称
    这样在加载页面之前,会先加载身份验证类
    在身份验证类里面去的用户名和模块名
    然后进行身份验证
    把权限信息,写入页面的相应的隐藏控件里面
    页面的page_load执行的时候
    隐藏控件里已经存储了该用户对该模块的详细权限信息(察看,修改,审批)
    根据这个信息,加载页面(不同权限,不同的加载方式)
    此思路已经成功运用到项目中
    隐藏控件我做了一个拥有完整权限信息属性的自定义label
      

  17.   

    事实上我说的那种方法是很简单的,比如一个页面a.aspx,其他有新增/修改/删除功能,当分配到用户的时候,可以拆分成这样:a.aspx?action=add,a.aspx?action=del,a.aspx?action=edit,当分配权限的时候相应给定url就可以了,但是也就是说在一个页面无法完成编辑/删除/新增的所有功能,因为其被拆分成3个url了,也就是说3个菜单,(但事实上还是一个页面,不会增加太多的工作量)
      

  18.   

    比如岗位A:只能分配新增权限,那么就分配a.aspx?action=add 这个url给他
    岗位B:可以新增/编辑,那么就分配a.aspx?action=add和a.aspx?action=edit这两个url,类推...
      

  19.   

    to killerwc(Elove^_^CS~B43) :
    good idea!谢谢了。那你是如何将模块的权限分配给各个用户的?
    模块名和用户是怎么样增加到数据库中的?是我们手工增加到数据库中,
    还是在程序运行的时候读取程序集的模块名,再存到数据库中??
     to mmkk() 
    你这样做,一个页面的增加,编辑就要分成2个页面了。而已在地址栏中
    显示a.aspx?action=add,用户会修改的,不大安全吧
      

  20.   

    你没有理解我的意思,用户当然可以修改,但是修改对了又怎么样?他还是没有权限访问,注意是将a.aspx?action=add,a.aspx?action=del...而不是a.aspx分配到权限中去
      

  21.   

    这样行不行?
    为页面上每个需要授权访问的控件设置权限,具体做法是为控件自定义一个属性,属性的值是授权的权限标识,例如permission="1,2,3,4"表示具有1,2,3,4类权限的人可以操作此控件。然后在自定义的httpmodule(或者基类)中获取(一般是从数据库中读取)当前访问者的权限表示,可以将这些信息存在HttpApplication.Context中以方便在页面上获取。最后定义一个所有页面共用的基类(继承System.Web.UI.Page),在此基类中重载OnPreRender方法(为了在Render之前改变控件状态,根据多态理论,它会被子类调用),在此方法遍历页面所有的控件,如果检测到某个控件定义了permission属性,则根据当前用户的权限信息和属性值可确定该用户的状态。以下是部分代码片段:
    //web.config

    <httpModules>
    <add name="PPMMHttpMoules " type="PPMM.ControlPermission.UserStateModule, PPMM" />
    </httpModules>// UserStateModule class
    namespace PPMM.ControlPermission
    {
    public class UserStateModule:IHttpModule
    {
    //…..
                       public void Init(HttpApplication app) 
    {
    // app.... += new EventHandler(...);
    app.BeginRequest+=new EventHandler(this.OnEnter);
    //或者是app.AuthenticateRequest += new EventHandler(this.OnEnter); 或其他
    }
    public void OnEnter(Object source, EventArgs eventArgs) 
    {
    HttpApplication app;
    HttpContext context;
    app = (HttpApplication)source;
    context = app.Context;
    //….将获得的用户信息存在context.Items中
    context.Items["UserState"] =….;
    }
    //…..
    }
    }
      

  22.   

    /基类CheckPermission
    namespace PPMM.ControlPermission
    {
    public class CheckPermission : System.Web.UI.Page
    {
    protected int permissionId=0;        
    public CheckPermission()
    {
    //…
    //获取在httpmodule中得到的当前用户权限信息
    //假设信息存在一个自定义对象UserState中,她有一个PermissionID属性
    UserState currUser=(UserState)this.Context.Items["UserState"];
    if(null!=currUser)
    {
    this.permissionId=currUser.PermissionID;
    }
    //…
    }
    //重载OnPreRender方法,她将会在页面内容产生之前调用,
    //改变页面状态,直接影响输出效果
    protected override void OnPreRender(EventArgs e)
    {
    this.SetControlsStatus(this.Page);
    base.OnPreRender(e);
    }
    //用递归的方法找出有permission属性的控件,并根据当前用户的permissionId
    //设置其状态(应该有其它比递归好的方法,没时间琢磨,只好递归了)
    private void SetControlsStatus(System.Web.UI.Control Ctrl)
    {
    if(!Ctrl.HasControls())
    {
    if(Ctrl is System.Web.UI.WebControls.WebControl)
    {
    System.Web.UI.WebControls.WebControl webCtrl=(System.Web.UI.WebControls.WebControl)Ctrl;
    if(webCtrl.Attributes["permission"]!=null)
    {
    string strPms=webCtrl.Attributes["permission"];
    if(!this.HasControlPermission(this.permissionId,strPms))
    {
    webCtrl.Enabled=false;//或其他操作
    }
    }
    }
    return;
    }
    foreach(Control ctrl in Ctrl.Controls)
    {
    this.SetControlsStatus(ctrl);
    }
    }
    //判断PermissionID在不在permission属性值所列的权限id列表中
    private bool HasControlPermission(int PermissionID, string PermissionList)
    {
    if(PermissionList==string.Empty) return true;
    bool reVal=false;
    string[] arrStr=PermissionList.Split(new char[] {','});
    for(int i=0;i<arrStr.Length;i++)
    {
    try
    {
    if(PermissionID==Convert.ToInt32(arrStr[i]))
    {
    reVal=true;
    break;
    }
    }
    catch
    {
    reVal=false;
    break;
    }
    }
    return reVal;
    }
    }
    }//页面中
    protected System.Web.UI.WebControls.Button Button1;
    protected System.Web.UI.WebControls.Button Button2;
    protected System.Web.UI.WebControls.Button Button3;
    protected System.Web.UI.WebControls.Button Button4;

    private void Page_Load(object sender, System.EventArgs e)
    {
    // Put user code to initialize the page here
    this.Button1.Attributes.Add("permission","1,2");
    this.Button2.Attributes.Add("permission","2,3");
    this.Button3.Attributes.Add("permission","3,4");
    this.Button4.Attributes.Add("permission","1,2,3,4");
    }
      

  23.   

    把我的问题,不要简单化。请细看我的问题!
    我想实现的功能呢,就是构建一个安全模块:
    1:可以取得各个页面中的按纽的name,text,按纽所在的页面(webform)的name放在database里面。
    [这个除了手动维护,好象还真没什么好办法。而且页面新增或修改后,用户的访问权限可能又得重新设置]
    2:给每个role或user,根据user权限级别高低,设置页面(webform)里面按纽可否执行,这些信息就存在database中
    [这个在有第一步的基础上,可以实现。根据当前请求的页面的名称可以取出用户对在本页按纽的权限信息,然后遍历页面控件树,看用户有无对控件操作的权限]
    3:应用执行时,已通过验证的user,根据usid从database取出对各个页面(webform)的按扭(操作)清单,放在全局缓存中。用户在页面对按扭执行时,就根据全局缓存中的操作清单,判断该用户对该按扭是否有权限执行。
    这样就实现了对按扭,也就是实现了操作上的授权安全。
    [当用户每请求一个页时,只取当前页的权限信息不是更好吗?因为一次只能请求一页,其他页都的信息都用不上,都取出来缓存比较浪费]
    4:如果可能的话,对httpapplication对象处理 AuthorizeRequest 事件应用程序级 (global.asax) 或者Http Module (实现 IHttpModule),实现第3步中的“就根据全局缓存中的操作清单,判断该用户对该按扭是否有权限执行。”
    [如果只取当前请求页的权限信息,在httmodule中取出来放在httpapplication.context中,也可以在所有页面的公共基类中取,放在一个保护成员对象中]
      

  24.   

    关注.微软的一个mvp好像还专门写了一篇文章.
      

  25.   

    to ajex:
    在哪里可以看到??to  kenfil:”3:应用执行时,已通过验证的user,根据usid从database取出对各个页面(webform)的按扭(操作)清单,放在全局缓存中。用户在页面对按扭执行时,就根据全局缓存中的操作清单,判断该用户对该按扭是否有权限执行。
    这样就实现了对按扭,也就是实现了操作上的授权安全。
    [当用户每请求一个页时,只取当前页的权限信息不是更好吗?因为一次只能请求一页,其他页都的信息都用不上,都取出来缓存比较浪费]  “怎么取得“只取当前页的权限信息”??因为我们是从数据库中取的,类似
    select 权限信息 where usid=:登陆用户ID and pagename =:当前页名称
    现在如何给 ”:当前页名称“ 赋值,在我们每个页面中硬编码给它一个值?
    比如,有aa.aspx,bb.aspx,我们要在这2个页面中“当前页名称=page_aa"和
    “当前页名称=page_bb",如果这样做的话,就不通用了,在自定义的httpmodule中如何实现”只取当前页的权限信息“?非常感谢你的贡献你的思想!
      

  26.   

    当前页面的名称就直接用当前资源的虚拟路径,这样可以保证所有页面的标识是唯一的。例如/ppmm/apabe.aspx。文件名好象还不行,因为不同目录可以有相同文件名。
    在httpmodule可以得到这个信息:
    app.Context.Request.FilePath
    //app 是 httpapplication
      

  27.   

    to kenfil(kenfil) :
    真的是对你,要说很多次的感谢。
    我现在实现了httpmodule对用户的验证,过一段时间,应该可以实现httpmodule,对用户的授权。(近段时间真是太忙了,心理太疲劳了!)我先看看有没有可能在运行时,可以通过对程序集的反射,取得个页面按钮的名称,这样就不用手工添加这些信息到数据库中!也希望大家可以提出更好的解决方案!
      

  28.   


    "当前页面的名称就直接用当前资源的虚拟路径,这样可以保证所有页面的标识是唯一的。例如/ppmm/apabe.aspx。文件名好象还不行,因为不同目录可以有相同文件名。
    在httpmodule可以得到这个信息:
    app.Context.Request.FilePath
    //app 是 httpapplication   "如果这样,我们在数据库中存的“前页面的名称”也要手工添加了?
    “前页面的名称”值填什么呢
      

  29.   

    不太明白你为什么非要把权限跟按钮绑的那么紧我现在也在做一个项目,其中就涉及到用户权限的问题,我用的方法烦一点,可能和你的思路不一致,但是运行的很好每个界面的操作权限基本上可以分为浏览,添加,删除,修改,还有信息的发布。这些权限有一个专门的模块进行控制,这个模块的一个典型函数就是判断用户是否具有相应的权限isAuthority(AuthorityName,UserID).浏览是最低权限,可以在Page_Load中进行判断,如果没有该权限,则转到错误处理页,添加,删除和修改都是有相应的按钮控制,所以如果用户没有相应的权限,该按钮的Enabled=false 或visible=false,信息发布在我这里是这样的,在Grid中有一个发布列,如果用户具有发布权限,则显示该列,否则隐藏,当然,在信息发布界面还要进行权限的判断。
        权限管理有一个专门的模块,.vb或编译成dll,想用的时候调用。有专门的权限分配管理界面。原来系统中是分角色和权限的,后来因为权限名比较少,直接操作权限比较灵活,就把角色去掉了。
        我觉得使用这种方式比存按钮要好,不用管按钮的名字,权限的名字容易记忆,比如“会议记录添加权限”
        不知道是不是你的意思
      

  30.   

    我的建议:
    把查看,创建,更新,删除四个模块独立出来,放在不同的四个WebForm,在数据库里根据不同的用户分配权限,如果用户没有权限,则不显示其相应的WebForm,这样也比较好控制。
    如果按照你的想法完全可以做到,不过比较麻烦,项目比较大,按照我的想法做可能比较合适。按照你的想法,可以在数据库建立权限表,对按钮为每个用户分配权限,登录时根据Forn验证的UserID初始化权限,点击按钮时根据UserID判断用户对按钮是否有操作权限!我也在搞权限控制,有机会可以继续交流:[email protected]
      

  31.   

    to  nkdzc:
      先感谢你,
    你这样的话,要在每个页面中写代码吗?
    我想实现的时候,不用在页面中(webform)写代码了,只要在这个页面的基类(page类)里面就可以了。因为我是在ASP.NET  里面实现。
    你的思想,从另外一个方面考虑,很不错!toluhanzhang(夏日凉风)
    "把查看,创建,更新,删除四个模块独立出来,放在不同的四个WebForm"
    可以具体些吗,这样我不大容易完全理解你的意思
      

  32.   

    这样不用记忆控件名,也不用记忆页名,
    在PAGE-LOAD中调用相关的方法就可以很灵活,
    在进行按钮验证时就调用相应的方法,
    很实用的
      

  33.   

    正要做这部分,
    luhanzhang(夏日凉风) 的方法太不方便,也不专业,同一个页面的处理要分成四页?ykn(ykn)  i agree with him.
      

  34.   

    to  xuzhenhua21 :
    感觉你意见很有建设性,可以再具体写吗,比如可以写出代码或伪代码吗
    这样我才可以理解你的意思,和你更好得交流!很感谢你,分数一定会有的,哈哈!
      

  35.   

    如果你可以规范化你空间的命名或者按钮空间TEXT属性(如插入操作都叫添加)的命名的化可以使用如下办法:
    1、编写一个方法(比如叫pageCtrl),输入一个PAGE的实例,可以遍历该实例中的所有控件,你可以在该方法中直接控制.ID=="某个名称"或.TEXT=="某个名称"的控件的各种属性。
    2、在每个页面的formload事件中调用该函数,如pageCtrl(this);步骤1的代码我公司的计算机中有,如果你对此方法感兴趣并且星期一还没找到更好的方法的话的话发电子邮件给我([email protected]),我会把代码贴给你