0

我正在尝试在我的动态数据网站上设置角色,但遇到了问题。

在我由 Generic Principal 设置的时间和点击默认页面之间,我的主体的角色丢失了。主体仍列为 context.user,因为当我调试会话并检查 context.user 对象时,我设置的用户就是我设置的用户;但与该用户相关的所有角色似乎都丢失了。

这就是我要做的事情。

登录页面

public partial class Login : System.Web.UI.Page
{
    string[] masterServiceResult;

protected void btnSubmit_Click(object sender, EventArgs e)
{
    if (IsAuthenticUser(login_email.Text, login_password.Text))
    {
        FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, masterServiceResult[0], DateTime.Now, DateTime.Now.AddMinutes(30), false, masterServiceResult[2], FormsAuthentication.FormsCookiePath);
        string encryptedCookie = FormsAuthentication.Encrypt(ticket);
        HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedCookie);
        Response.Cookies.Add(cookie);
        Response.Redirect(FormsAuthentication.GetRedirectUrl(masterServiceResult[0], true));

    }
}

private bool IsAuthenticUser(string email, string password)
{
    MembershipService membershipService = new MembershipService();
    var result = membershipService.GetUserAndRoleFromCredentials(email, password);

    //result is an array with userName, userId, error(bool) as string, and error message if any
    if (bool.Parse(result[3]) == false)
    {
        masterServiceResult = result;
        return true;
    }

    return false;
}
}

然后在 Global.asax 我已附加到 AuthenticateRequest 事件

void Global_AuthenticateRequest(object sender, EventArgs e)
{
    if (Request.IsAuthenticated)
        SetupRoles();
}

private void SetupRoles()
{
    if (Context.User != null)
    {
        string cookieName = FormsAuthentication.FormsCookieName;

        HttpCookie authCookie = Context.Request.Cookies[cookieName];

        if (authCookie == null)
            return;

        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);

        string[] roles = authTicket.UserData.Split(new char[] { '|' });

        IIdentity fi = Context.User.Identity;
        IPrincipal pi = new GenericPrincipal(fi, roles);


        Context.User = pi;

        //sets the application principal to use the logged on user account
        System.Threading.Thread.CurrentPrincipal = System.Web.HttpContext.Current.User;

        // sanity check to ensure the role was set up.
        if (User.IsInRole("Admin"))
        {
            int i = 0; // debug line
        }
    }
}

此时一切都按预期工作;我的测试帐户现在设置为 context.user,Current Principal 用户设置为当前用户,并且 Admin 的用户角色导致“int i=0”调试行被命中。但是,一旦默认页面 Page_Load 被点击,情况就不再如此了。

默认页面。更新 01/03/12 以显示另一个测试用例。protected void Page_Load(object sender, EventArgs e) { System.Collections.IList visibleTables = MetaModel.Default.VisibleTables;

    // this line comes back as false, though at this point the user name is the same.
    if (User.IsInRole("Admin"))
    {
        int i = 0;
    }

    // the next 4 lines of code is a work around I can do to retrieve the roles from the ticket.
    string cookieName = FormsAuthentication.FormsCookieName;
    HttpCookie authCookie = Context.Request.Cookies[cookieName];
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    // this line of code will correctly show the users role
    string[] roles = authTicket.UserData.Split(new char[] { '|' });

    foreach (var table in MetaModel.Default.Tables)
    {
        var permissions = ((MetaTable)table).GetTablePermissions(roles);
        if (permissions.Contains(TablePermissionsAttribute.Permissions.DenyRead))
            visibleTables.Remove(table);
    }

    if (visibleTables.Count == 0)
    {
        throw new InvalidOperationException("There are no accessible tables. Make sure that at least one data model is registered in Global.asax and scaffolding is enabled or implement custom pages.");
    }
    Menu1.DataSource = visibleTables;
    Menu1.DataBind();
}

*更新:我能够从身份验证票证中获取用户的角色,并且主体是正确的,但我对 User.IsInRole 行失败的原因感到困惑。

4

0 回答 0