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

在我由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行失败 .