我只是發表我已經嘗試了代碼。這只是我採取的一種方法。但我需要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/)? –