Introduction
In this application, Windows identity and Windows principal object are customized to fit the Web environment. The IsInRole
method of Identity and Principal are customized to check the User role list from the database .The Page/Component wise security is also provided in a simple way.
In case people in the LAN (same Domain) want access to some intranet sites, then for authentication you need not have to maintain any Login Table to store the login details such as ID, Password, EmailId, etc. You can use your workstation login id and password as the login credentials. The login credentials will query the LDAP and return your IdentityCode
["Cn
"] property which can be sent to your RMS database and get the logged in users information to the page.
How Does this Application Work?
There are two classes CustomIdentity and CustomPrincipal
which customize the IPrincipal
and IIdentity
class respectively.
CustomIdentity
- Place the properties for logged user (whatever you think is needed regarding the logged in user)
IsInRole
method will return whether the logged user role exists in the role list container or not?
IsRoleURL
method will tell whether the logged user role has access to the requested pages/Business Component?
GetIdentity Method
This returns CustomIdentity
object filled with the logged user data.
- This method takes the domain
UserId
and Password
as parameters and verifies with the ADS.
- If logged user is present in the domain, then his identity code will be returned from the ADS.
- Pass this identity code to the database and get the user information and bind to the properties of the
CustomIdentity
object.
- Return the
CustomIdentity
object.
UnauthenticatedIdentity Method
- It returns a new empty
CustomIdentity
object which can be called when the user signs out.
- The above mentioned are internal methods which will be called through the
CustomPrincipal
class.
CustomPrincipal
IsInRole
and IsRoleURL
methods call CustomIdentity
's IsInRole
and IsRoleURL
methods respectively.
IsRoleURL
method will tell whether the logged user role has access to requested pages/Business Component?
AuthenticateUser
calls GetIdentity
of CustomIdentity
and returns customprincipal
.
- This
customprincipal
object is set as the current context user.
SignOut
calls UnauthenticatedIdentity
method of Identity.
The below mentioned classes are used in the demo project.
DataCache
Used for caching the data and persist till the end of the application. Add to cache and retrieve cache methods are used to store and retrieve data from the cache.
UIBase
Set this as a pagebase class for all web.UI.Pages
. In the pageload event, check the existence of requested URL's access for that role.
LoginAuthendicationWithADS
- On Application Start, fetch the Roles And URLs from database and put it in cache.
- On session start, the
LoggedIn
data in Session is set to "NO
".
- Enter the domain userid and password and click Go.
- In this event, you call the
CustomPrincipal AuthenticateUser
method to get the user details.
- If user is authenticated, then
LoggedIn
data in Session is set to "YES
".
Using the Code
DataBase
Blocks of code should be set as style "Formatted
" like this:
//
//
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
Here call the AuthenicateUser
method of CustomPrincipal
:
if (CustomPrincipal.AuthenticateUser(UserID, UserPwd))
{
if (HttpContext.Current.Session["LoggedIn"] == null)
{
HttpContext.Current.Session.Add("LoggedIn", "Yes");
}
else
HttpContext.Current.Session["LoggedIn"] = "Yes";
isLoggedIn = true;
}
CustomPrincipal Class
Set this CustomPrincipal
object as the CurrentContext
user:
#region User Property
public static IPrincipal User
{
set
{
if (HttpContext.Current != null)
HttpContext.Current.User = value;
Thread.CurrentPrincipal = value;
}
}
#endregion
This method calls the GetIdentity
method of CustomIdentity
:
#region Methods
public static bool AuthenticateUser(string UserID, string UserPwd)
{
CustomIdentity objIdentity = CustomIdentity.GetIdentity(UserID, UserPwd);
if (objIdentity.IsAuthenticated)
{
objPrincipal = new CustomPrincipal(objIdentity);
User = objPrincipal;
}
return objIdentity.IsAuthenticated;
}
CustomIdentity Class
Check the UserID
, Password
with ADS and get the user identity code:
#region AuthedicateMe with ADS
private static string AuthedicateMe(string UserID,string Password)
{
string DN = System.Configuration.ConfigurationManager.AppSettings
["DomainName"].ToString();
string strLDPPath = "LDAP://" + DN;
string strEntryPath = "(&(objectClass=user)(anr=" + UserID + "))";
try
{
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
Pass this user identity code to the database and get the UserInfo
. Set this information in appropriate properties of the identity class:
#region AuthenticateandAuthorizeMe
private static CustomIdentity AuthenticateandAuthorizeMe(string UserID, string Password)
{
try
{
PortalIdentity = new CustomIdentity();
strIdcode = AuthedicateMe(UserID, Password);
try
{
Common comm = new Common();
DbDataReader dreader = comm.GetLoggedUserData(strIdcode);
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)
{
foreach (DataRow drow in dtRoleURL.Select
("RoleName= '" + PortalIdentity.strUserRole +"'"))
{
PortalIdentity.lstUrl.Add(drow["URLName"].ToString());
}
}
PortalIdentity.lstRoleURL.Add(PortalIdentity.strUserRole, PortalIdentity.lstUrl);
}
The customidentity
class will expose the properties publicly, but not the method. All methods are internal to the library. They are exposed through the customprincipal
class.
Conclusion
The above application helps you in customizing your current context user object.
History
- 17th May, 2007: Initial post