Edited by SomeNewKid. Please post code between <code> and </code> tags.
Hi,
Warning - Long Post :)
I've pasted some code below but I thought some background on what we're up to might help as well:
* We've got an existing intranet with 2000+ users
* We do not have any "anonymous" users - every user is authenticated against our own user table.
* We've got a core collaboration engine for these users to work together on different projects (we call them web groups). There are many thousands of these web groups. Our web group model is very similar to DNN's (users, tabs, and roles)
* In addition to project collaboration, our users are broken down into a myriad of special interest groups (also using the collaboration engine)
* We're experimenting with porting these special interest groups groups over to DNN portals to give them the ability to define their own content / modules to use
* Some of our web groups are accessible to ALL users while others are security to specific user lists.
* We're relying on our existing infrastructure to handle most security type stuff
* Our existing security model DOES NOT use the .NET authentication stuff - all ASPX pages are inherited from a BasePage (like DNN) that handles security through cookies
* A big part of our mods is that we're maintaining a single set of users in the USERS table and drawing from that when adding users to specific portals. These USERS are actually pulled from our existing database when the user signs in.
* And finally, all of this is experimental at this point :) We're PATIENTLY waiting for DNN 3 to see if we'll take it to the finish. From what we've been reading about DNN 3, we're very hopeful
Why are we doing this? DNN contains some very nice / tight code - kudos to the core development team. We're looking for a more dynamic engine to power our collobration efforts across the enterprise by giving users more power in designing their interface. DNN's skins / modules (we'll be defining a fixed set of choices for each) gives us a great tool for getting there.
Below are the main snippets from our global.asax.vb and security.vb files (please note that we're still goofing around with this but it's pretty close). We've also added some routines to the SQL data provider to call our database for authentication / user mapping stuff.
Someone had questions on encryption - ours predates .NET and is very weak - just a simple routine that scrambles characters. Check DNN's global.asax.vb for .NET's FormsAuthentication.Encrypt / Decrypt for stronger scrambling.
Here's some code for review purposes only. It won't run without all the variable declarations, etc.:
Code @ Top of Application_AuthenticateRequest()
If Request.IsAuthenticated = False And Convert.ToString(_portalSettings.GroupId).Trim <> "" Then
' we're not authenticated - check the our credentials
' and login from there (if available)
If Not (Request.Cookies("UN") Is Nothing) Then
sUserName = Request.Cookies("UN").Value.ToString()
' decode our password
sTempPW = Request.Cookies("UP").Value.ToString()
If (sTempPW <> "") Then
bFoundCookie = True
' dscramble the password
sPassword = OurDecrypt(sTempPW)
End If
dr = DataProvider.Instance().CustomLogin(sUserName, sPassword)
If dr.Read() Then
sUserId = Convert.ToString(dr("Pros_Id"))
sUserName = Convert.ToString(dr("webid"))
sPassword = Convert.ToString(dr("webpsw"))
sFirstName = Convert.ToString(dr("FirstName"))
sLastName = Convert.ToString(dr("LastName"))
sUnit = ""
sStreet = ""
sCity = ""
sState = ""
sPostalCode = ""
sCountry = ""
sTelephone = ""
sEmail = Convert.ToString(dr("Email"))
End If
dr.Close()
If sUserId = "-1" Then
' no good - user id not found in our table - redirect
' to our login...
Response.Redirect("/aspx/SRedir.aspx?urlout=" & "~/" & glbDefaultPage & "?tabid=" & _portalSettings.HomeTabId.ToString)
End If
' validate that the our user exists on the DNN Users table
dr = DataProvider.Instance().GetUserByOurId(sUserId)
If dr.Read() Then
iDNNUserId = Convert.ToInt32(dr("UserID"))
End If
dr.Close()
If iDNNUserId = -1 Then
' not on the DNN user table so add them
iDNNUserId = DataProvider.Instance().AddOurUser(sUserId, sFirstName, sLastName, sUnit, sStreet, sCity, sState, sPostalCode, sCountry, sTelephone, sEmail, sUserName, sPassword, 0)
Else
' we found em - sync the basic user info
DataProvider.Instance().UpdateUser(iDNNUserId, sFirstName, sLastName, sUnit, sStreet, sCity, sState, sPostalCode, sCountry, sTelephone, sEmail, sUserName, sPassword)
End If
' now check the group portal to see if it maps to a web group
portalUserId = PortalSecurity.Custom_ValidatePortalUser(_portalSettings.GroupId, _portalSettings.PortalId, iDNNUserId, sUserId)
' if the user is part of the portal then setup authentication for DNN
If portalUserId <> -1 Then
FormsAuthentication.SetAuthCookie(Convert.ToString(iDNNUserId), False)
Response.Redirect("/dnn/" & glbDefaultPage & "?tabid=" & _portalSettings.ActiveTab.TabId.ToString)
ElseIf _portalSettings.PortalId <> 0 And Convert.ToString(_portalSettings.GroupId).Trim() <> "" Then
Response.Write("Security Violation...")
Response.End()
End If
Else
' not logged into the our system yet so do that now
Response.Redirect("/aspx/SRedir.aspx?urlout=" & "/dnn/" & glbDefaultPage & "?tabid=" & _portalSettings.ActiveTab.TabId.ToString)
End If
End If
'' end of Application_AuthenticateRequest logic.
Custom routines from Security.VB:
Public Shared Function Custom_ValidatePortalUser(ByVal sGroupId As String, ByVal PortalId As Integer, ByVal SiteUserId As Integer, ByVal sUserId As String) As Integer
Dim dr As IDataReader
Dim UserId As Integer
dr = DataProvider.Instance().GetPortalUser(PortalId, SiteUserId)
UserId = -1
If dr.Read Then
If Convert.ToBoolean(dr("Authorized")) Then
UserId = Convert.ToInt32(dr("UserId"))
End If
dr.Close()
' check if portal is linked to Web Group
' resync roles based upon current team membership
' (eg, user is no longer part of a council)
' these kinds of updates are handled by the
' interface in our custom app
Else
dr.Close()
' Security
' check the Portal.GroupId
' if AllGroups Then if user isn't on this portal's
' user table add them to PortalUsers and add to
' Authorized Users role for this portal
' setup for role handling...
Dim objRoles As RoleController = New RoleController
Dim arrRoles As ArrayList = CBO.FillCollection(DataProvider.Instance().GetPortalRoles(PortalId), GetType(RoleInfo))
If sGroupId.Trim().ToLower() = "all" Then
' this group is open to all members so autogen
' the portal's user record
UserId = Custom_AddPortalUser(PortalId, SiteUserId, objRoles, arrRoles)
ElseIf sGroupId.Trim() <> "" Then
' it's a Web Group - get security settings from there and update
' portal membership as needed
Dim sConfSecure As String = "-1"
Dim sConfType As String = ""
Dim sParticip As String = "-1"
dr = DataProvider.Instance().GetGroupInfo(sGroupId)
If dr.Read() Then
sConfSecure = Convert.ToString(dr("ConfSecure"))
sConfType = Convert.ToString(dr("ConfType"))
End If
dr.Close()
Select Case sConfSecure
Case "-1"
Case "01", "S3"
' these are Web Group portals that are visible and their
' contents are visible so gen the user
UserId = Custom_AddPortalUser(PortalId, SiteUserId, objRoles, arrRoles)
dr = DataProvider.Instance().GetGroupTeamRecord(sGroupId, sUserId)
If dr.Read() Then
sParticip = Convert.ToString(dr("PARTICIP"))
End If
dr.Close()
If sParticip <> "-1" Then
' user is part of the council
' add the Council Member to DNN UserRoles
Custom_AddPortalUserRole(PortalId, SiteUserId, "Council Member", objRoles, arrRoles)
If sParticip = "MODERATOR" Then
' part of leadership
Custom_AddPortalUserRole(PortalId, SiteUserId, "Council Leadership", objRoles, arrRoles)
End If
End If
Case Else
' look at the Group Team to see if user can access this portal
sParticip = "-1"
dr = DataProvider.Instance().GetGroupTeamRecord(sGroupId, sUserId)
If dr.Read() Then
sParticip = Convert.ToString(dr("PARTICIP"))
End If
dr.Close()
If sParticip <> "-1" Then
' the person is on the group's team so add them to the DNN
' portaluser table
UserId = Custom_AddPortalUser(PortalId, SiteUserId, objRoles, arrRoles)
If sParticip = "MODERATOR" Then
' part of group moderators role
Custom_AddPortalUserRole(PortalId, SiteUserId, "Moderator", objRoles, arrRoles)
End If
End If
End Select
End If
End If
' update last login into portal
If UserId <> -1 Then
DataProvider.Instance().UpdatePortalUser(PortalId, SiteUserId, True, Now)
End If
Return (UserId)
End Function
Public Shared Function Custom_AddPortalUser(ByVal PortalId As Integer, ByVal SiteUserId As Integer, ByVal objRoles As RoleController, ByVal arrRoles As ArrayList) As Integer
Dim UserId As Integer
UserId = DataProvider.Instance().AddPortalUser(PortalId, SiteUserId, True)
Custom_GenPortalUserAutoRoles(PortalId, SiteUserId, objRoles, arrRoles)
End Function
Public Shared Sub Custom_GenPortalUserAutoRoles(ByVal PortalId As Integer, ByVal SiteUserId As Integer, ByVal objRoles As RoleController, ByVal arrRoles As ArrayList)
Dim i As Integer
Dim objRole As RoleInfo
For i = 0 To arrRoles.Count - 1
objRole = CType(arrRoles(i), RoleInfo)
If objRole.AutoAssignment = True Then
objRoles.AddUserRole(PortalId, SiteUserId, objRole.RoleID, Null.NullDate)
End If
Next
End Sub
Public Shared Sub Custom_AddPortalUserRole(ByVal PortalId As Integer, ByVal SiteUserId As Integer, ByVal RoleName As String, ByVal objRoles As RoleController, ByVal arrRoles As ArrayList)
' add's a user to a portal role based upon role name
Dim i As Integer
Dim objRole As RoleInfo
For i = 0 To arrRoles.Count - 1
objRole = CType(arrRoles(i), RoleInfo)
If objRole.RoleName = RoleName Then
objRoles.AddUserRole(PortalId, SiteUserId, objRole.RoleID, Null.NullDate)
End If
Next
End Sub
''' End of Security.vb updates
We've also built a bunch of "interface" modules to load our controls in the DNN interface. It's a bit tricky, but we're getting there.
ps Sorry for the formatting - paste the code into a VB module and let the IDE beautify it for you.
Whew! I hope this helps!
Shawn