CustomIdentity






4.05/5 (7投票s)
自定义身份、使用 ADS 的自定义主体
引言
在此应用程序中,Windows 身份和 Windows 主体对象被自定义以适应 Web 环境。Identity 和 Principal 的 IsInRole
方法被自定义为从数据库中检查用户角色列表。页面/组件级别的安全性也以简单的方式提供。
如果 LAN (同一域) 中的用户需要访问某些内网站点,那么在身份验证时,您无需维护任何登录表来存储登录详细信息,如 ID、密码、EmailId 等。您可以使用您的工作站登录 ID 和密码作为登录凭据。登录凭据将查询 LDAP 并返回您的 IdentityCode
["Cn
"] 属性,该属性可以发送到您的 RMS 数据库,然后获取登录用户的信息到页面。
此应用程序如何工作?
有两个类 CustomIdentity 和 CustomPrincipal
,它们分别自定义了 IPrincipal
和 IIdentity
类。
CustomIdentity
- 为登录用户放置属性(您认为关于登录用户需要的任何内容)
IsInRole
方法将返回登录用户的角色是否存在于角色列表容器中?IsRoleURL
方法将告诉登录用户的角色是否有权访问请求的页面/业务组件?
GetIdentity 方法
此方法返回填充了登录用户数据的 CustomIdentity
对象。
- 此方法以域
UserId
和Password
作为参数,并与 ADS 进行验证。 - 如果登录用户存在于域中,那么他的身份代码将从 ADS 返回。
- 将此身份代码传递到数据库并获取用户信息,然后绑定到
CustomIdentity
对象的属性。 - 返回
CustomIdentity
对象。
UnauthenticatedIdentity 方法
- 它返回一个新的空
CustomIdentity
对象,该对象可以在用户注销时调用。 - 以上提到的方法是内部方法,将通过
CustomPrincipal
类调用。
CustomPrincipal
IsInRole
和IsRoleURL
方法分别调用CustomIdentity
的IsInRole
和IsRoleURL
方法。IsRoleURL
方法将告诉登录用户的角色是否有权访问请求的页面/业务组件?AuthenticateUser
调用CustomIdentity
的GetIdentity
并返回customprincipal
。- 此
customprincipal
对象被设置为当前上下文用户。 SignOut
调用 Identity 的UnauthenticatedIdentity
方法。
以下类在演示项目中有所使用。
DataCache
用于缓存数据并一直持久化到应用程序结束。Add to cache 和 retrieve cache 方法用于将数据存储和检索到缓存中。
UIBase
将此设置为所有 web.UI.Pages
的页面基类。在 pageload 事件中,检查请求的 URL 是否存在对该角色的访问权限。
LoginAuthendicationWithADS
- 在 Application Start 时,从数据库中获取 Roles And URLs 并将其放入缓存。
- 在 session start 时,Session 中的
LoggedIn
数据被设置为 "NO
"。 - 输入域用户 ID 和密码,然后单击“Go”。
- 在此事件中,您调用
CustomPrincipal AuthenticateUser
方法来获取用户详细信息。 - 如果用户已通过身份验证,则 Session 中的
LoggedIn
数据被设置为 "YES
"。
Using the Code
DataBase
代码块应设置为“Formatted
”样式,如下所示
//
//
--Sample DataBase Script:
--(to Run this application)
GO
CREATE TABLE [transact].[URL_Master](
[URLID] [int] NOT NULL,
[URLName] [varchar](500) NOT NULL,
) ON [PRIMARY]
GO
CREATE TABLE [transact].[RoleMaster](
[RoleId] int NOT NULL,
[RoleName] [varchar](50) NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [transact].[User](
[identityCode] [int] NOT NULL,
[Name] [varchar](50) NOT NULL,
[Details] [varchar](500) NULL,
[D_O_J] [datetime] NULL,
) ON [PRIMARY]
GO
CREATE TABLE [transact].[User_URL_Role](
[URLID] [int] NOT NULL ,
[RoleID] [int] NOT NULL
) ON [PRIMARY]
GO
CREATE TABLE [transact].[UserRole](
[IdentityCode] [varchar](10) NOT NULL,
[RoleID] [int] NULL
) ON [PRIMARY]
GO
//
UILayer
在此处调用 CustomPrincipal
的 AuthenicateUser
方法
if (CustomPrincipal.AuthenticateUser(UserID, UserPwd))
{
// Success, so we can access web site details.
if (HttpContext.Current.Session["LoggedIn"] == null)
{
HttpContext.Current.Session.Add("LoggedIn", "Yes");
}
else
HttpContext.Current.Session["LoggedIn"] = "Yes";
isLoggedIn = true;
}
CustomPrincipal Class
将此 CustomPrincipal
对象设置为 CurrentContext
用户
#region User Property
/// <summary>
/// Get or set the current <see cref="IPrincipal" />
/// object representing the user's identity.
/// </summary>
/// <remarks>
/// When running under IIS the HttpContext.Current.User value
/// is used, otherwise the current Thread.CurrentPrincipal
/// value is used.
/// </remarks>
public static IPrincipal User
{
set
{
if (HttpContext.Current != null)
HttpContext.Current.User = value;
Thread.CurrentPrincipal = value;
}
}
#endregion
此方法调用 CustomIdentity
的 GetIdentity
方法
#region Methods
public static bool AuthenticateUser(string UserID, string UserPwd)
{
// Gets the CustomIdentity after verifying with ADS and
// retrieving User info from Database
CustomIdentity objIdentity = CustomIdentity.GetIdentity(UserID, UserPwd);
//if Authenticated then set the current Context user as CustomPrincipal
if (objIdentity.IsAuthenticated)
{
objPrincipal = new CustomPrincipal(objIdentity);
User = objPrincipal;
}
return objIdentity.IsAuthenticated;
}
CustomIdentity Class
使用 ADS 检查 UserID
、Password
并获取用户身份代码
#region AuthedicateMe with ADS
/// <summary>
/// Get the logged in users IDcode from the ADS
/// </summary>
/// <returns>string IDcode</returns>
private static string AuthedicateMe(string UserID,string Password)
{
//System.Configuration.ConfigurationManager.AppSettings["serverpath"].ToString()
string DN = System.Configuration.ConfigurationManager.AppSettings
["DomainName"].ToString();
string strLDPPath = "LDAP://" + DN;
string strEntryPath = "(&(objectClass=user)(anr=" + UserID + "))";
try
{
//provides easy access to active directory from managed code
DirectoryEntry rootEntry = new DirectoryEntry
(strLDPPath, DN + "\\" + UserID, Password);
// DirectoryEntry rootEntry =
// new DirectoryEntry(null, "WDE" + "\\" + UserID, Password);
//DirectoryEntry Class can be used to authenticate a
//username and password against active directory.
//You can force authentication to occur by retrieving the nativeObject property.
// Bind to the native object to force authentication to happen
Object objnative = rootEntry.NativeObject;
// "User authenticated" Move to the next page.
//Directory Searcher: perform queries against the active directory hierarchy
DirectorySearcher objDSearch = new DirectorySearcher(rootEntry);
objDSearch.SearchScope = SearchScope.Subtree;
objDSearch.Filter = strEntryPath;
objDSearch.PropertiesToLoad.Add("cn");
objDSearch.PageSize = 5;
objDSearch.ServerTimeLimit = new TimeSpan(0, 10, 0);
objDSearch.ClientTimeout = new TimeSpan(0, 10, 0);
SearchResult queryResults = objDSearch.FindOne();
if (queryResults != null)
{
// string PasswordString = System.Text.Encoding.Default.GetString
// ((Byte[])queryResults.Properties["userPassword"][0]);
return queryResults.Properties["cn"][0].ToString();
}
else
{
return string.Empty;
}
}
catch (Exception ex)
{
throw new Exception("Invalid password/UserID.Please Try again", ex);
}
}
#endregion
将此用户身份代码传递到数据库并获取 UserInfo
。将此信息设置在身份类的相应属性中
#region AuthenticateandAuthorizeMe
/// <summary>
/// Retrieves the Get UserInfo from the
/// </summary>
/// <returns></returns>
private static CustomIdentity AuthenticateandAuthorizeMe(string UserID, string Password)
{
try
{
PortalIdentity = new CustomIdentity();
//gets Identity code from LDAP
strIdcode = AuthedicateMe(UserID, Password);
try
{
// Get User Data
Common comm = new Common();
DbDataReader dreader = comm.GetLoggedUserData(strIdcode);
//Set the values to the Custom Identity's Properties
if (dreader.HasRows)
{
PortalIdentity.blnIsAuthenticated = true;
while (dreader.Read())
{
PortalIdentity.strIDcode = strIdcode;
PortalIdentity.strName = dreader["Name"].ToString();
PortalIdentity.strUserRole = dreader["RoleName"].ToString();
PortalIdentity.strUserRoleId = dreader["Roleid"].ToString();
if (dreader["D_O_J"] != null && dreader["D_O_J"] != DBNull.Value
&& (!string.IsNullOrEmpty(dreader["D_O_J"].ToString())))
PortalIdentity.dtRegisterDate = Convert.ToDateTime(dreader["D_O_J"].ToString());
if (dtRoleURL != null)
{
//Bind the URL to a list Container
foreach (DataRow drow in dtRoleURL.Select
("RoleName= '" + PortalIdentity.strUserRole +"'"))
{
PortalIdentity.lstUrl.Add(drow["URLName"].ToString());
}
}
PortalIdentity.lstRoleURL.Add(PortalIdentity.strUserRole, PortalIdentity.lstUrl);
}
customidentity
类将公开属性,但不会公开方法。所有方法都是库的内部方法。它们通过 customprincipal
类公开。
结论
以上应用程序可帮助您自定义当前的上下文用户对象。
历史
- 2007 年 5 月 17 日:初始帖子