65.9K
CodeProject 正在变化。 阅读更多。
Home

CustomIdentity

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.05/5 (7投票s)

2007年5月17日

CPOL

3分钟阅读

viewsIcon

31250

downloadIcon

425

自定义身份、使用 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 方法分别调用 CustomIdentityIsInRole 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

在此处调用 CustomPrincipalAuthenicateUser 方法

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

此方法调用 CustomIdentityGetIdentity 方法

#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 检查 UserIDPassword 并获取用户身份代码

#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 日:初始帖子
© . All rights reserved.