none
求助关于ASP.NET中基于角色的验证授权的一个问题... RRS feed

  • 问题

  • 按照http://www.cnblogs.com/microchuan/archive/2006/04/25/384147.aspx
    这里面提供的方法,我已经成功的把用户的角色字符串添加到了USER对象里面去了,可以通过User.IsInRole()方法得到结果...

    在通过User.IsInRole("1")方法得到TRUE和web.config里面配了:
    <location path="Admin">
    <system.web>
    <authorization>
    <deny users="*"/>
    <allow roles="1"/>
    </authorization>
    </system.web>
    </location>
    的情况下还是无法访问admin里面的东西,这实在太矛盾了,请问我还差什么工作没有做吗?
    谢谢...

     

     

    结果我又试了一下,相当于<allow roles>的这条没什么用,allow和deny都不管用,到底要怎样做才行啊...

    2009年1月14日 10:17

答案

  • 你的做法不对啊。正确的步骤:(照着做即可得到满意的结果)

    1,web.config的配置设置:

    Code Snippet


    <location path="Admin">
        <system.web>
          <authorization>
            <allow roles="1"/>
            <deny users="*"/>
          </authorization>
        </system.web>
      </location>

     

    2,新加用户登录界面,用来设置哪位用户将有权限.Login.aspx

     

    Code Snippet

    <%@ Page Language="C#" AutoEventWireup="true"%>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <script runat="server">

      protected void Button1_Click(object sender, EventArgs e)
      {
        String username = UserName.Text;

          if (username.EndsWith("mxh", StringComparison.InvariantCultureIgnoreCase) && Password.Text.EndsWith("mxh", StringComparison.InvariantCultureIgnoreCase))
          {
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
            username,
            DateTime.Now,
            DateTime.Now.AddMinutes(30),
            false,
            "1", //这里加入登录用户所具有的角色。
            FormsAuthentication.FormsCookiePath);
            string encTicket = FormsAuthentication.Encrypt(ticket);
            Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
            Response.Redirect(FormsAuthentication.GetRedirectUrl(username, false));
          }
          else
          {
            Response.Write("密码不正确");
          }
      }
    </script>

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
      <title></title>
    </head>
    <body>
      <form id="form1" runat="server">
      用户名:<asp:TextBox ID="UserName" runat="server" /> <br />
      密码:<asp:TextBox ID="Password" TextMode="password" runat="server" /> <br />
      <asp:Button ID="Button1" Text="登录" runat="server" onclick="Button1_Click" />
      </form>
    </body>
    </html>

     

     

    密码验证采取固定的写法,数据库验证类似,简单起见,采用固定的用户名mxh,密码mxh

     

    3,Global.asax里

    Code Snippet

    <%@ Application Language="C#" %>
    <script runat="server">
        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {
          string cookieName = FormsAuthentication.FormsCookieName;

          HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
          //HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
          if (null == authCookie)
          {
            // 没有身份验证 cookie。
            return;
          }
          FormsAuthenticationTicket authTicket = null;
          authTicket = FormsAuthentication.Decrypt(authCookie.Value);

          if (null == authTicket)
          {
            // 无法解密 Cookie。
            return;
          }

          string[] roles = authTicket.UserData.Split(new char[] { ',' });
          FormsIdentity id = new FormsIdentity(authTicket);
          System.Security.Principal.GenericPrincipal principal = new System.Security.Principal.GenericPrincipal(id, roles);
          Context.User = principal;
        }
      
    </script>

     

    注意是 Application_AuthenticateRequest 事件

     

    4:Admin目录下的文件

    Code Snippet

    protected void Page_Load(object sender, EventArgs e)
    {
      if (Page.User.IsInRole("1") == false)
      {
        Response.Write("权限被禁止");
        Response.End();
        return;
      }
    }

     

     

    2009年1月14日 15:54
    版主

全部回复

  • <allow roles="1"/>

    <deny users="*"/>
    有顺序问题
    2009年1月14日 12:01
    版主
  •  

    运行时,授权模块从最本地的配置文件开始,循环访问 allowdeny 元素,直到它找到适合特定用户帐户的第一个访问规则。然后,该授权模块根据找到的第一个访问规则是 allow 还是 deny 规则来允许或拒绝对 URL 资源的访问。

    *号是拒绝所有用户,所以,你先deny,则role=1的也被拒绝了

    2009年1月14日 12:04
    版主
  •  孟宪会 写:

     

    运行时,授权模块从最本地的配置文件开始,循环访问 allowdeny 元素,直到它找到适合特定用户帐户的第一个访问规则。然后,该授权模块根据找到的第一个访问规则是 allow 还是 deny 规则来允许或拒绝对 URL 资源的访问。

    *号是拒绝所有用户,所以,你先deny,则role=1的也被拒绝了

     

    我换了顺序还是没用,现在是allow role 不管写什么都没用,我的roles信息加到user里面是在global.asax里面的Application_AuthorizeRequest方法里面的...

     // 提取窗体身份验证 cookie
            string cookieName = FormsAuthentication.FormsCookieName;

            HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
            //HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
            if (null == authCookie)
            {
                // 没有身份验证 cookie。
                return;
            }
            FormsAuthenticationTicket authTicket = null;
            authTicket = FormsAuthentication.Decrypt(authCookie.Value);

            if (null == authTicket)
            {
                // 无法解密 Cookie。
                return;
            }

            string[] roles = authTicket.UserData.Split(new char[] { ',' });
            FormsIdentity id = new FormsIdentity(authTicket);
            System.Security.Principal.GenericPrincipal principal = new System.Security.Principal.GenericPrincipal(id, roles);
            Context.User = principal;

     

    会不会是这个方法是在验证完了以后才执行的,所以验证roles信息的时候user里面的roles信息还没有,所以没法使用?

    2009年1月14日 13:39
  • 你的做法不对啊。正确的步骤:(照着做即可得到满意的结果)

    1,web.config的配置设置:

    Code Snippet


    <location path="Admin">
        <system.web>
          <authorization>
            <allow roles="1"/>
            <deny users="*"/>
          </authorization>
        </system.web>
      </location>

     

    2,新加用户登录界面,用来设置哪位用户将有权限.Login.aspx

     

    Code Snippet

    <%@ Page Language="C#" AutoEventWireup="true"%>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <script runat="server">

      protected void Button1_Click(object sender, EventArgs e)
      {
        String username = UserName.Text;

          if (username.EndsWith("mxh", StringComparison.InvariantCultureIgnoreCase) && Password.Text.EndsWith("mxh", StringComparison.InvariantCultureIgnoreCase))
          {
            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
            username,
            DateTime.Now,
            DateTime.Now.AddMinutes(30),
            false,
            "1", //这里加入登录用户所具有的角色。
            FormsAuthentication.FormsCookiePath);
            string encTicket = FormsAuthentication.Encrypt(ticket);
            Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
            Response.Redirect(FormsAuthentication.GetRedirectUrl(username, false));
          }
          else
          {
            Response.Write("密码不正确");
          }
      }
    </script>

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
      <title></title>
    </head>
    <body>
      <form id="form1" runat="server">
      用户名:<asp:TextBox ID="UserName" runat="server" /> <br />
      密码:<asp:TextBox ID="Password" TextMode="password" runat="server" /> <br />
      <asp:Button ID="Button1" Text="登录" runat="server" onclick="Button1_Click" />
      </form>
    </body>
    </html>

     

     

    密码验证采取固定的写法,数据库验证类似,简单起见,采用固定的用户名mxh,密码mxh

     

    3,Global.asax里

    Code Snippet

    <%@ Application Language="C#" %>
    <script runat="server">
        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {
          string cookieName = FormsAuthentication.FormsCookieName;

          HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
          //HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];
          if (null == authCookie)
          {
            // 没有身份验证 cookie。
            return;
          }
          FormsAuthenticationTicket authTicket = null;
          authTicket = FormsAuthentication.Decrypt(authCookie.Value);

          if (null == authTicket)
          {
            // 无法解密 Cookie。
            return;
          }

          string[] roles = authTicket.UserData.Split(new char[] { ',' });
          FormsIdentity id = new FormsIdentity(authTicket);
          System.Security.Principal.GenericPrincipal principal = new System.Security.Principal.GenericPrincipal(id, roles);
          Context.User = principal;
        }
      
    </script>

     

    注意是 Application_AuthenticateRequest 事件

     

    4:Admin目录下的文件

    Code Snippet

    protected void Page_Load(object sender, EventArgs e)
    {
      if (Page.User.IsInRole("1") == false)
      {
        Response.Write("权限被禁止");
        Response.End();
        return;
      }
    }

     

     

    2009年1月14日 15:54
    版主
  •  

    既然你的Page.User.IsInRole("1")为true了,就可以执行 admin的操作了,为什么还不能看呢?你的Page.User.IsInRole("1")为true怎么检测出来的?
    2009年1月14日 15:59
    版主
  •  

    终于弄出来了,不是什么步骤问题,是因为global里面的方法名问题,正确的方法应该是你写的这个Application_AuthenticateRequest,而我之前看的教程上写的是:Application_AuthorizeRequest,两个单词很像啊,我觉得还是像我说的那样,这个方法肯定是放到验证后面去执行了,所以通不过...

     

    困扰我多天的问题终于解决了,泪流满面啊,多谢版主大大帮助啊...

    2009年1月14日 16:22
  • 老大啊,为什么我照着你的说法做还是不行呢,55555....我用的是vs2008

    2009年9月11日 7:55
  • 我的也是vs2008

    你创建文件系统的网站测试,应该是没有问题的

    【孟子E章】
    2009年9月11日 8:42
    版主