Hi ba-insight Yes, there is a function I have already created in the component for using the Windows Authentical without ADs, follows these step: * In TTT_ADs.vb find Private Function AddWinUser(ByVal PortalID As Integer, ByVal LoginID As String) As Integer
* Change Private --> Public * Before End Function add: Return UserID * In global.asax.vb, replace all code I have modifed with this code
If TypeOf Context.User.Identity Is WindowsIdentity Then
Dim sUser As String = Context.User.Identity.Name
Dim dr As SqlDataReader = objUser.GetSingleUserByUsername(_portalSettings.PortalId, sUser)
Dim objADs As New TTT_ADs()
If dr.Read() Then
intUserId = dr("UserId")
Else
intUserId = objADs.AddWinUser(_portalSettings.PortalId, sUser)
If Not intUserId = -1 Then
objUser.AddUserRole(_portalSettings.PortalId, _portalSettings.RegisteredRoleId, intUserId)
End If
End If
Else
If IsNumeric(Context.User.Identity.Name) Then
intUserId = Int32.Parse(Context.User.Identity.Name)
End If
End If
* Rebuild your project Please verify that impersonate is implemented in Web.config, and IIS security setting should
NOT allows Anonimous access I've received quite a few of requests using my component W/O Active Directory. I'm going to modify it to suite with all these cases. Updated component will be sent to you soon.
Hi Tran008 There is a reserve Private Function AddWINUser(...) As Integer, to use if you have problem with your Active Directory access, it add minimum info generated from login ID instead of getting info from ADs. It should return the UserID. I've forgot it.
Please replace all function AddWINUser with this
Public Function AddWinUser(ByVal PortalID As Integer, ByVal LoginID As String) As Integer
Dim UserID As Integer
Dim objUser As New UsersDB()
Dim objSecurity As New PortalSecurity()
Dim _portalSettings As PortalSettings = CType(HttpContext.Current.Items("PortalSettings"), PortalSettings)
Dim fName As String = Left(LoginID, InStr(LoginID, "\") - 1)
Dim lName As String = Right(LoginID, (Len(LoginID) - InStr(LoginID, "\")))
'Add new user to DNN database with minimum info generate from user login
UserID = objUser.AddUser(PortalID, fName, lName, "", "", "", "", "", "", "", LoginID, LoginID, LoginID, "true", -1)
Return UserID
End Function
Notes: this fix the problem you mention above only. I received a suggestion from gismapper a better way to get ADs object. I'll send this update soon.
Hi Tam, I have made the said correction and now my Windows authentification works. I wonder, is there a way to tell DotNetNuke that a Role has "host" privilege? Thanks
Hi jmbezeau You could do that by changing the name of "host" user in table user (which has IsSuperUser = 1) into the name of user you want to assign "host" privilege. * format for this username must be DOMAIN\UserName * DNN accept only one user with IsSuperUser
value set to 1
I am just starting out with DNN. I have been trying all day to get Windows Auth to work the way I expect. Please aslo send me the code you refered to for AD integration. Thank You, Steven BerkHolz StevenBerkHolz@TESCOGroup.com
Hey TTT, It appears the AddDNNRoles method adds UserRoles if they correspond with existing DNN roles but does not add new Roles . I've modified the AddDNNRoles to add UserRoles and Roles to DNN. Thus my AddDNNRoles is now as follows: Basically reads all roles
into a HashTable through DataReader now we have key/value(RoleName/RoleId) pairs Next we query AD for a user's Roles we attempt to add everyone to the HashTable, if it collides, means its an existing role and is ignored, otherwise we insert a new role into
hashtable as a key with a value of -1. We go ahead and add the role to DNN Now we've got this HashTable that has -1 values which means they're new. We want to add them to the UserRoles but we don't have RoleID for then. Now reset datareader for a new set of
GetPortalRoles() Use dr("RoleName) as key value to grab HashTable Item, if its -1 means its a new Role and we need to add a UseRole with the following Criteria RoleName from The HashTable and Role Id from the DataReader...... Hope it makes sense, hope its
sound logic.....Seems to work so far in testing
Public Sub AddDNNRoles(ByVal PortalID As Integer, ByVal UserID As Integer, ByVal LoginID As String)
Dim objUser As New UsersDB()
Dim arrGroup As New ArrayList()
Dim sGroup As String
Dim iCount As Integer
Dim i As Integer
Dim oFile As System.IO.File
Dim oWrite As System.IO.StreamWriter
'See method below regarding this conructor
Dim userInfo As New DirectoryEntry(GetPath(LoginID))
'set authentication info for using ADs
SetADsSecurity(userInfo)
'Groups
Dim drPortalRoles As SqlDataReader = objUser.GetPortalRoles(PortalID)
Dim ht As New Hashtable()
Dim st As New Stack()
While drPortalRoles.Read
ht.Add(drPortalRoles("RoleName"), drPortalRoles("RoleId"))
End While
Try
iCount = userInfo.Properties("MemberOf").Count
If iCount > 0 Then
'Retrive group membership from Windows ADs and add to arraylist
For i = 0 To iCount - 1
Dim gADs As String = userInfo.Properties("MemberOf").Item(i)
Dim myGroup As String = Left(gADs, (InStr(gADs, ",") - 1))
myGroup = myGroup.Replace("CN=", "")
myGroup = myGroup.Replace("\", "")
Try
ht.Add(myGroup, -1)
objUser.AddRole(PortalID, myGroup.Replace("CN=", ""), myGroup.Replace("CN=", ""), 0.0, 0, 0, "")
'Adding Group to DNN
Catch
'Hash collision group already exists
'Do nothing but ignore
End Try
Next
drPortalRoles = Nothing 'Kill previous DataReader
'Now updating user roles.....
drPortalRoles = objUser.GetPortalRoles(PortalID)
Dim rName As String
While drPortalRoles.Read
rName = drPortalRoles(1)
'Look in HashTable for matching Keys from DataReader
'If its undefined ( < 0 ) means its a new Role that also needs to be added
' also need to be added to UserRoles
If Double.Parse(ht.Item(rName)) < 0 Then
objUser.AddUserRole(PortalID, drPortalRoles("RoleID"), UserID, "")
End If
End While
End If
Catch Exc As System.Exception
'Uh oh
Dim strExc As String = Exc.ToString
End Try
End Sub
The domain\username is not a qualified CN in our AD thus the following was derived to
Private Function GetPath(ByVal LoginId As String) As String
Dim root As Object = GetObject("GC://rootDSE")
Dim strNameContext As String = root.Get("DefaultNamingContext")
Dim loginUser As String = Right(LoginId, Len(LoginId) - InStr(LoginId, "\"))
Dim strUsrPath As String = ""
Try
Dim obEntry As DirectoryEntry = New DirectoryEntry("GC://CN=Users," + strNameContext)
obEntry.Username = ConfigurationSettings.AppSettings("ADsUserName")
obEntry.Password = ConfigurationSettings.AppSettings("ADsPassword")
Dim srch As DirectorySearcher = New DirectorySearcher(obEntry, "(userPrincipalName=" + loginUser + "*)")
Try
Dim res As SearchResult = srch.FindOne()
strUsrPath = res.Path.ToString()
Catch e As Exception
e.StackTrace.ToString()
End Try
Catch e As Exception
e.StackTrace.ToString()
End Try
Return strUsrPath
End Function
Ok I added a second Hashtable to evaluate against. In the previous code it was not updating all of a user's role memberships. The following should rectify the problem. It now Reads all the user's group memberships in Active Directory into one HashTable, Reads
all DNN groups into another HashTable. We hash all of the user's ad entries into htADUserRoles and attempt to hash all of them into htDNN, If htDNN.add() is successful the Role is added via UserDB component. Otherwise its ignored. Now to add UserRole, we take
the htADUserRole and get a 2'nd DataReader and see if the dr(1) exist as a key in the htADUserRole if it does, add the UserRole via UserDB component Hope it helps....
Public Sub AddDNNRoles(ByVal PortalID As Integer, ByVal UserID As Integer, ByVal LoginID As String)
Dim objUser As New UsersDB()
Dim sGroup As String
Dim iCount As Integer
Dim i As Integer
Dim userInfo As New DirectoryEntry(GetPath(LoginID))
'set authentication info for using ADs
SetADsSecurity(userInfo)
'Groups
Dim drPortalRoles As SqlDataReader = objUser.GetPortalRoles(PortalID)
Dim htADUserRole As New Hashtable()
Dim htDNN As New Hashtable()
While drPortalRoles.Read
htDNN.Add(drPortalRoles("RoleName"), drPortalRoles("RoleId"))
End While
Try
iCount = userInfo.Properties("MemberOf").Count
If iCount > 0 Then
'Retrive group membership from Windows ADs and add to arraylist
For i = 0 To iCount - 1
Dim gADs As String = userInfo.Properties("MemberOf").Item(i)
Dim myGroup As String = Left(gADs, (InStr(gADs, ",") - 1))
myGroup = myGroup.Replace("CN=", "")
myGroup = myGroup.Replace("\", "")
htADUserRole.Add(myGroup, myGroup)
Try
htDNN.Add(myGroup, -1)
objUser.AddRole(PortalID, myGroup.Replace("CN=", ""), myGroup.Replace("CN=", ""), 0.0, 0, 0, "")
Catch
'Hash collision group already exists
End Try
Next
drPortalRoles = Nothing
drPortalRoles = objUser.GetPortalRoles(PortalID)
While drPortalRoles.Read
'Grab DNN Roles that are associated with this user and insert to DB
If htADUserRole.Contains(drPortalRoles(1)) Then
objUser.AddUserRole(PortalID, drPortalRoles("RoleID"), UserID, "")
End If
End While
End If
Catch Exc As System.Exception
'UhOh
End Try
End Sub
Hi Bandit_193 There were some reasons for me let the component not to import groups from ADs into DNN database automatically: * In some network, there are big amount of security groups. Like my company, we use ADs group to handle security issue based on projects
(1 group for each project). We have about 50 new groups/month. It would be headache for admin when they want to assign security role when creating new tab or adding new module with such big number of roles. * Code in the component runs anytime a new user login
to DNN, even if there is no new group to import, it causes some performance problem in a big network. I'm thinking of creating a separate module for DNN admin to handle all these ADs job (such as import new DNN roles from ADs, synchronize user group membership
and DNN role, delete roles/group, assign membership for both DNN & ADs....) all of these tasks should be done by DNN admin only. And DNN portal will become a central tool for Windows Network administration. What do you think about this idea? Tam, Tran Minh
tamttt
Contributor
2500 Points
500 Posts
Re: Windows Authentication
Apr 16, 2003 02:20 PM|LINK
If TypeOf Context.User.Identity Is WindowsIdentity Then Dim sUser As String = Context.User.Identity.Name Dim dr As SqlDataReader = objUser.GetSingleUserByUsername(_portalSettings.PortalId, sUser) Dim objADs As New TTT_ADs() If dr.Read() Then intUserId = dr("UserId") Else intUserId = objADs.AddWinUser(_portalSettings.PortalId, sUser) If Not intUserId = -1 Then objUser.AddUserRole(_portalSettings.PortalId, _portalSettings.RegisteredRoleId, intUserId) End If End If Else If IsNumeric(Context.User.Identity.Name) Then intUserId = Int32.Parse(Context.User.Identity.Name) End If End If* Rebuild your project Please verify that impersonate is implemented in Web.config, and IIS security setting should NOT allows Anonimous access I've received quite a few of requests using my component W/O Active Directory. I'm going to modify it to suite with all these cases. Updated component will be sent to you soon.tamttt
Contributor
2500 Points
500 Posts
Re: Windows Authentication
Apr 16, 2003 02:34 PM|LINK
Public Function AddWinUser(ByVal PortalID As Integer, ByVal LoginID As String) As Integer Dim UserID As Integer Dim objUser As New UsersDB() Dim objSecurity As New PortalSecurity() Dim _portalSettings As PortalSettings = CType(HttpContext.Current.Items("PortalSettings"), PortalSettings) Dim fName As String = Left(LoginID, InStr(LoginID, "\") - 1) Dim lName As String = Right(LoginID, (Len(LoginID) - InStr(LoginID, "\"))) 'Add new user to DNN database with minimum info generate from user login UserID = objUser.AddUser(PortalID, fName, lName, "", "", "", "", "", "", "", LoginID, LoginID, LoginID, "true", -1) Return UserID End FunctionNotes: this fix the problem you mention above only. I received a suggestion from gismapper a better way to get ADs object. I'll send this update soon.jmbezeau
Member
30 Points
9 Posts
Re: Windows Authentication
Apr 16, 2003 04:12 PM|LINK
Jean-Michel Bezeau
Revenu Québec
tran008
Member
15 Points
3 Posts
Re: Windows Authentication
Apr 16, 2003 04:27 PM|LINK
tamttt
Contributor
2500 Points
500 Posts
Re: Windows Authentication
Apr 17, 2003 03:24 AM|LINK
JohnnyNoir
Member
105 Points
21 Posts
Re: Windows Authentication
Apr 17, 2003 05:48 AM|LINK
stevenberkho...
Member
5 Points
1 Post
Re: Windows Authentication
Apr 17, 2003 08:04 PM|LINK
bandit_193
Member
15 Points
3 Posts
Re: Windows Authentication
Apr 18, 2003 07:49 PM|LINK
Public Sub AddDNNRoles(ByVal PortalID As Integer, ByVal UserID As Integer, ByVal LoginID As String) Dim objUser As New UsersDB() Dim arrGroup As New ArrayList() Dim sGroup As String Dim iCount As Integer Dim i As Integer Dim oFile As System.IO.File Dim oWrite As System.IO.StreamWriter 'See method below regarding this conructor Dim userInfo As New DirectoryEntry(GetPath(LoginID)) 'set authentication info for using ADs SetADsSecurity(userInfo) 'Groups Dim drPortalRoles As SqlDataReader = objUser.GetPortalRoles(PortalID) Dim ht As New Hashtable() Dim st As New Stack() While drPortalRoles.Read ht.Add(drPortalRoles("RoleName"), drPortalRoles("RoleId")) End While Try iCount = userInfo.Properties("MemberOf").Count If iCount > 0 Then 'Retrive group membership from Windows ADs and add to arraylist For i = 0 To iCount - 1 Dim gADs As String = userInfo.Properties("MemberOf").Item(i) Dim myGroup As String = Left(gADs, (InStr(gADs, ",") - 1)) myGroup = myGroup.Replace("CN=", "") myGroup = myGroup.Replace("\", "") Try ht.Add(myGroup, -1) objUser.AddRole(PortalID, myGroup.Replace("CN=", ""), myGroup.Replace("CN=", ""), 0.0, 0, 0, "") 'Adding Group to DNN Catch 'Hash collision group already exists 'Do nothing but ignore End Try Next drPortalRoles = Nothing 'Kill previous DataReader 'Now updating user roles..... drPortalRoles = objUser.GetPortalRoles(PortalID) Dim rName As String While drPortalRoles.Read rName = drPortalRoles(1) 'Look in HashTable for matching Keys from DataReader 'If its undefined ( < 0 ) means its a new Role that also needs to be added ' also need to be added to UserRoles If Double.Parse(ht.Item(rName)) < 0 Then objUser.AddUserRole(PortalID, drPortalRoles("RoleID"), UserID, "") End If End While End If Catch Exc As System.Exception 'Uh oh Dim strExc As String = Exc.ToString End Try End SubThe domain\username is not a qualified CN in our AD thus the following was derived toPrivate Function GetPath(ByVal LoginId As String) As String Dim root As Object = GetObject("GC://rootDSE") Dim strNameContext As String = root.Get("DefaultNamingContext") Dim loginUser As String = Right(LoginId, Len(LoginId) - InStr(LoginId, "\")) Dim strUsrPath As String = "" Try Dim obEntry As DirectoryEntry = New DirectoryEntry("GC://CN=Users," + strNameContext) obEntry.Username = ConfigurationSettings.AppSettings("ADsUserName") obEntry.Password = ConfigurationSettings.AppSettings("ADsPassword") Dim srch As DirectorySearcher = New DirectorySearcher(obEntry, "(userPrincipalName=" + loginUser + "*)") Try Dim res As SearchResult = srch.FindOne() strUsrPath = res.Path.ToString() Catch e As Exception e.StackTrace.ToString() End Try Catch e As Exception e.StackTrace.ToString() End Try Return strUsrPath End Functionbandit_193
Member
15 Points
3 Posts
Re: Windows Authentication
Apr 19, 2003 12:11 AM|LINK
Public Sub AddDNNRoles(ByVal PortalID As Integer, ByVal UserID As Integer, ByVal LoginID As String) Dim objUser As New UsersDB() Dim sGroup As String Dim iCount As Integer Dim i As Integer Dim userInfo As New DirectoryEntry(GetPath(LoginID)) 'set authentication info for using ADs SetADsSecurity(userInfo) 'Groups Dim drPortalRoles As SqlDataReader = objUser.GetPortalRoles(PortalID) Dim htADUserRole As New Hashtable() Dim htDNN As New Hashtable() While drPortalRoles.Read htDNN.Add(drPortalRoles("RoleName"), drPortalRoles("RoleId")) End While Try iCount = userInfo.Properties("MemberOf").Count If iCount > 0 Then 'Retrive group membership from Windows ADs and add to arraylist For i = 0 To iCount - 1 Dim gADs As String = userInfo.Properties("MemberOf").Item(i) Dim myGroup As String = Left(gADs, (InStr(gADs, ",") - 1)) myGroup = myGroup.Replace("CN=", "") myGroup = myGroup.Replace("\", "") htADUserRole.Add(myGroup, myGroup) Try htDNN.Add(myGroup, -1) objUser.AddRole(PortalID, myGroup.Replace("CN=", ""), myGroup.Replace("CN=", ""), 0.0, 0, 0, "") Catch 'Hash collision group already exists End Try Next drPortalRoles = Nothing drPortalRoles = objUser.GetPortalRoles(PortalID) While drPortalRoles.Read 'Grab DNN Roles that are associated with this user and insert to DB If htADUserRole.Contains(drPortalRoles(1)) Then objUser.AddUserRole(PortalID, drPortalRoles("RoleID"), UserID, "") End If End While End If Catch Exc As System.Exception 'UhOh End Try End Subtamttt
Contributor
2500 Points
500 Posts
Re: Windows Authentication
Apr 21, 2003 12:44 PM|LINK