我正在开发一个复杂的网站,用户有多个角色。用户还耦合在DB中的其他项目上,这些项目连同他们的角色将定义他们可以在网站上看到和做什么。
目前,一些用户有一个以上的角色,但由于其复杂的结构,网站一次只能处理一个角色。
这个想法是一个用户登录并在网站的角落有一个下拉列表,在那里他可以选择他的角色之一。如果他只有一个角色,就没有下降权。
现在,我将最后选择的角色值与他的其他设置一起存储在DB中。当他回来的时候,这样的角色仍然被记住。
下拉列表的价值应该可以在整个网站上访问。我想做两件事:
Session中。IsInRole方法或编写IsCurrentlyInRole方法以检查对当前选定角色的所有访问,而不是所有角色,原始的IsInRole方法也是如此对于会话存储部分,我认为在Global.asax中这样做会更好
protected void Application_AuthenticateRequest(Object sender, EventArgs e) {
if (User != null && User.Identity.IsAuthenticated) {
//check for roles session.
if (Session["CurrentRole"] == null) {
NASDataContext _db = new NASDataContext();
var userparams = _db.aspnet_Users.First(q => q.LoweredUserName == User.Identity.Name).UserParam;
if (userparams.US_HuidigeRol.HasValue) {
var role = userparams.aspnet_Role;
if (User.IsInRole(role.LoweredRoleName)) {
//safe
Session["CurrentRole"] = role.LoweredRoleName;
} else {
userparams.US_HuidigeRol = null;
_db.SubmitChanges();
}
} else {
//no value
//check amount of roles
string[] roles = Roles.GetRolesForUser(userparams.aspnet_User.UserName);
if (roles.Length > 0) {
var role = _db.aspnet_Roles.First(q => q.LoweredRoleName == roles[0].ToLower());
userparams.US_HuidigeRol = role.RoleId;
Session["CurrentRole"] = role.LoweredRoleName;
}
}
}
}
}但显然这会产生运行时错误。Session state is not available in this context.
IPrincipal?)在没有失去所有其他功能的情况下使用IsCurrentlyInRole任何帮助都是非常感谢的。
发布于 2011-02-18 13:02:32
是的,您不能访问Application_AuthenticateRequest中的会话。
我已经创建了自己的CustomPrincipal。我将向你们展示我最近所做的事情:
public class CustomPrincipal: IPrincipal
{
public CustomPrincipal(IIdentity identity, string[] roles, string ActiveRole)
{
this.Identity = identity;
this.Roles = roles;
this.Code = code;
}
public IIdentity Identity
{
get;
private set;
}
public string ActiveRole
{
get;
private set;
}
public string[] Roles
{
get;
private set;
}
public string ExtendedName { get; set; }
// you can add your IsCurrentlyInRole
public bool IsInRole(string role)
{
return (Array.BinarySearch(this.Roles, role) >= 0 ? true : false);
}
}如果存在身份验证票证(用户已登录),我的Application_AuthenticateRequest将读取cookie:
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Request.Cookies[My.Application.FORMS_COOKIE_NAME];
if ((authCookie != null) && (authCookie.Value != null))
{
Context.User = Cookie.GetPrincipal(authCookie);
}
}
public class Cookie
{
public static IPrincipal GetPrincipal(HttpCookie authCookie)
{
FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
if (authTicket != null)
{
string ActiveRole = "";
string[] Roles = { "" };
if ((authTicket.UserData != null) && (!String.IsNullOrEmpty(authTicket.UserData)))
{
// you have to parse the string and get the ActiveRole and Roles.
ActiveRole = authTicket.UserData.ToString();
Roles = authTicket.UserData.ToString();
}
var identity = new GenericIdentity(authTicket.Name, "FormAuthentication");
var principal = new CustomPrincipal(identity, Roles, ActiveRole );
principal.ExtendedName = ExtendedName;
return (principal);
}
return (null);
}
}我已经扩展了我的cookie,添加了身份验证票据的UserData。我把额外的信息放在这里:
这是在loging之后创建cookie的函数:
public static bool Create(string Username, bool Persistent, HttpContext currentContext, string ActiveRole , string[] Groups)
{
string userData = "";
// You can store your infos
userData = ActiveRole + "#" string.Join("|", Groups);
FormsAuthenticationTicket authTicket =
new FormsAuthenticationTicket(
1, // version
Username,
DateTime.Now, // creation
DateTime.Now.AddMinutes(My.Application.COOKIE_PERSISTENCE), // Expiration
Persistent, // Persistent
userData); // Additional informations
string encryptedTicket = System.Web.Security.FormsAuthentication.Encrypt(authTicket);
HttpCookie authCookie = new HttpCookie(My.Application.FORMS_COOKIE_NAME, encryptedTicket);
if (Persistent)
{
authCookie.Expires = authTicket.Expiration;
authCookie.Path = FormsAuthentication.FormsCookiePath;
}
currentContext.Response.Cookies.Add(authCookie);
return (true);
}现在,您可以在应用程序中的任何地方访问您的信息:
CustomPrincipal currentPrincipal = (CustomPrincipal)HttpContext.User;这样您就可以访问您的自定义主体成员: currentPrincipal.ActiveRole
当用户更改角色(活动角色)时,您可以重写cookie。
我忘了说我在authTicket.UserData中存储了一个JSON序列化类,因此反序列化和解析很容易。
您可以找到更多的信息这里。
发布于 2011-02-17 15:12:23
如果您真的希望用户一次只拥有一个活动角色(就像想要覆盖IsInRole所暗示的那样),那么也许将用户的所有“潜在”角色存储在一个单独的位置是最简单的,但实际上只允许它们一次处于一个ASP.NET身份验证角色中。当他们选择一个新角色时,使用内置方法将其从当前角色中删除并添加到新角色中。
https://stackoverflow.com/questions/5030227
复制相似问题