I'm doing authenticating for my admin page. I followed examples from various websites, but it's always kicking me out back to the log in page every time I try to access the product page.

This is my code

login.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        if (User.Identity.IsAuthenticated && Request.QueryString["ReturnUrl"] != "")
        {
            divError.Visible = true;
            divError.InnerHtml = accessErrorMessage;
        }
    }
}

protected void btn_enter_Click(object sender, EventArgs e)
{
    using (var db = new MainDB()) 
    {
        administrator=db.Administrators.Where(q => q.Name == txtUsername.Text && q.Password == txtPassword.Text).FirstOrDefault();

        if(administrator!=null)
        {
            administrator.DateLastLogin = DateTime.Now;
            roles = administrator.Role;
            adminID = administrator.AdministratorId;
            db.SaveChanges();

            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
                1, // Ticket version
                adminID.ToString(),                     // Username associated with ticket
                DateTime.UtcNow,                        // Date/time issued
                DateTime.UtcNow.AddMinutes(30),         // Date/time to expire
                true,                                   // "true" for a persistent user cookie              
                **roles,        // User-data, in this case the roles(data example: product,feedback,subscribes** 
                FormsAuthentication.FormsCookiePath);   // Path cookie valid for

            // Encrypt the cookie using the machine key for secure transport
            string hash = FormsAuthentication.Encrypt(ticket);
            HttpCookie cookie = new HttpCookie(
               FormsAuthentication.FormsCookieName, // Name of authentication cookie
               hash); // Hashed ticket

            // Set the cookie's expiration time to the tickets expiration time
            if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;

            // Add the cookie to the list for outgoing response
            Response.Cookies.Add(cookie);

            // Redirect to requested URL, or homepage if no previous page
            // requested
            string returnUrl = Request.QueryString["ReturnUrl"];
            if (returnUrl == null)
            {
                returnUrl = "~/admin/";
            }
            // Don't call FormsAuthentication.RedirectFromLoginPage since it
            // could 
            // replace the authentication ticket (cookie) we just added
            Response.Redirect(returnUrl);
        }
        else
        {
            divError.Visible = true;
            divError.InnerHtml = loginErrorMessage;
        }
      //if (FormsAuthentication.Authenticate(txtUsername.Text, txtPassword.Text))
            //{
            //    FormsAuthentication.RedirectFromLoginPage(txtUsername.Text, false);
            //}     
     }  

global.asax

void Application_AuthenticateRequest(object sender, EventArgs e)
{
    if(Request.IsAuthenticated)
    {
        FormsIdentity identity = (FormsIdentity)HttpContext.Current.User.Identity;

        //Add the roles to the User Principal
        HttpContext.Current.User = new System.Security.Principal.GenericPrincipal(HttpContext.Current.User.Identity, identity.Ticket.UserData.Split(new char[] { ',' }));
    }
}

web.config

<location path="admin/product">
<system.web>
  <authorization>
    <!--<allow users="admin"/>-->
    <allow roles="product"/>
    <deny users="*"/>
  </authorization>
</system.web>

<location path="admin/spotlight">
<system.web>
  <authorization>
    <!--<allow users="admin"/>-->
    <allow roles="spotlight"/>
    <deny users="*"/>
  </authorization>
</system.web>

<location path="admin/career">
<system.web>
  <authorization>
    <!--<allow users="admin"/>-->
    <allow roles="career"/>
    <deny users="*"/>
  </authorization>
</system.web>

<location path="admin/emailshare">
<system.web>
  <authorization>
    <!--<allow users="admin"/>-->
    <allow roles="emailshare"/>
    <deny users="*"/>
  </authorization>
</system.web>

Am I doing something wrong here?

有帮助吗?

解决方案

You are first allowing a role, but then denying all users.

The rules are executed in order so try to specify the most specific rule as the last.

<deny users="*"/>
<allow roles="emailshare"/>

Another thing, you are not setting the Principal after authenticating the user from the DB. You need to set the user in the HttpContext and flag is as Authenticated. Otherwise if (Request.IsAuthenticated) will always be false.

GenericIdentity userIdentity = 
    new GenericIdentity(ticket.Name);   
GenericPrincipal userPrincipal = 
    new GenericPrincipal(userIdentity, roles);   
Context.User = userPrincipal;

Note that the roles parameter is a comma-seperated string.

Also, wwouldn't it be easier to use the build-in provider model? That prevents you for writing all the authentication code yourself. You can then create your custom Membership provider with your own data access logic when required.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top