我只是发表我已经尝试了代码。这只是我采取的一种方法。但我需要epxperts评论说这是好主意或没有对于安全性,性能等
第1步:定义自定义接口它继承的IPrincipal
public interface ICustomPrincipal : IPrincipal
{
string[] Roles { get; set; }
string Country { get; set; }
string Region { get; set; }
string Department { get; set; }
string CurrentProductId { get; set; }
bool HasAcceptedTerms { get; set; }
}
第2步:使用以上实现自定义主界面
public class CustomPrincipal : ICustomPrincipal
{
private IPrincipal principal;
public CustomPrincipal(IPrincipal principal, WindowsIdentity identity)
{
this.Identity = identity;
this.principal = principal;
}
#region IPrincipal Members
public IIdentity Identity { get; private set; }
public bool IsInRole(string role)
{
return (principal.IsInRole(role));
}
public string Department { get; set; }
public string[] Roles { get; set; }
public string Country { get; set; }
public string Region { get; set; }
public string CurrentProductId { get; set; }
public bool HasAcceptedTerms { get; set; }
#endregion
}
第3步:定义您自己的角色提供程序。也使该供应商的web.config文件条目并将其设置为默认提供
public class MyCustomRoleProvider : RoleProvider
{
List<string> _roles = new List<string> { "System Administrators", "Product Administrators", "Users", "Guests" };
public override string[] GetRolesForUser(string username)
{
//TODO: Get the roles from DB/Any other repository and add it to the list and return as array
return _roles.ToArray();
}
public override bool IsUserInRole(string username, string roleName)
{
if (_roles.Contains(roleName))
{
//this.Department = "My Department";
return true;
}
else
return false;
}
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override string ApplicationName
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public override void CreateRole(string roleName)
{
throw new NotImplementedException();
}
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
throw new NotImplementedException();
}
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
throw new NotImplementedException();
}
public override string[] GetAllRoles()
{
throw new NotImplementedException();
}
public override string[] GetUsersInRole(string roleName)
{
throw new NotImplementedException();
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override bool RoleExists(string roleName)
{
throw new NotImplementedException();
}
}
第4步:下面实现事件
注:我serialzing其他用户信息到的FormsAuthenticationTicket。我的网站已启用Windows身份验证。
protected void WindowsAuthentication_OnAuthenticate(Object source, WindowsAuthenticationEventArgs e)
{
if (null == Request.Cookies.Get("authCookie"))
{
var userId = e.Identity.Name;
//TODO: You may need to get the user details like country, region etc. from DB. For simplicity, I have just assigned user roles (multiple) property
//Instead of string array, you should use your own Class to hold this custom data and then serialize
string[] userRoles = new string[] { "System Administrators", "Users" };
StringWriter writer = new StringWriter();
XmlSerializer xs = new XmlSerializer(typeof(string[]));
xs.Serialize(writer, userRoles);
FormsAuthenticationTicket formsAuthTicket =
new FormsAuthenticationTicket(
1,
userId,
DateTime.Now,
DateTime.Now.AddMinutes(20),
false,
writer.ToString());
var encryptedTicket = FormsAuthentication.Encrypt(formsAuthTicket);
HttpCookie httpCookie = new HttpCookie("authCookie", encryptedTicket);
Response.Cookies.Add(httpCookie);
}
}
第5步:使用PostAuthenticateRequest事件将您的RolePrincipal包装到您的CustomPrincipal中。这对于将数据保存在Principal对象中是很有必要的,以便您可以在应用程序的任何部分访问它。不要使用Application_AuthenticateRequest来覆盖WINDOWS主体对象。如果您启用了角色提供者,ASP。NET将实际上用角色主体来替换WINDOWS主体。
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
HttpCookie authCookie = Context.Request.Cookies.Get("authCookie");
FormsAuthenticationTicket formsAuthenticationTicket = FormsAuthentication.Decrypt(authCookie.Value);
CustomPrincipal newUser = new CustomPrincipal(User, (WindowsIdentity)User.Identity);
StringReader sr = new StringReader(formsAuthenticationTicket.UserData);
XmlSerializer xs = new XmlSerializer(typeof(string[]));
object ret = xs.Deserialize(sr);
newUser.Roles = (string[]) ret;
Context.User = newUser;
}
正如Preben所建议的那样,每当用户转向不同的产品时,我都会更新cookie。
希望这有助于愿意存储更多用户数据与Windows身份验证相结合的用户。
请让我知道是否有更好的方法来实现目标。
告诉我们一些代码 – TRR
[你有什么试过](http://mattgemmell.com/2008/12/08/what-have-you-tried/)? –