我正在尝试在我的动态数据网站上设置角色,但遇到了问题。
在我由 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 行失败的原因感到困惑。