Tam's Original Thread has gotten a little long, so I thought I'd start a new one for DNN3.0.
I want to "enhance" DNN to support the following use-case...
* If a user is logged into a domain, visiting the DNN site should automatically recognize them and show menu options based on the Groups they have been assigned in their domain.
And since DNN3.0 has the new membership provider model, this change should be a snap.
I started by making a new class project for my custom providers. First I added a reference to the MemberRole.dll in DNN3.0's bin. Then...
public class ADAMMembershipProvider : Microsoft.ScalableHosting.Security.MembershipProvider
...and wrote a bunch of code using System.DirectoryServices to access my LDAP domain.
Now I had to change the web.config.
This turns on Windows Authentication so that HttpContext.Current.User.Identity.Name becomes "DOMAIN\username".
<identity impersonate="true"/>
<authentication mode="Windows">
</authentication>
And this plugs in my first provider...
<membership userIsOnlineTimeWindow="15">
<providers>
<add name="ADAMMembershipProvider"
type="CustomProviders.ADAMMembershipProvider, CustomProviders"
domain="MONORAIL"
server="localhost:50389"
...
/>
</providers>
</membership>
And it works like a charm. (note: I had to add "admin" as a User in my domain since DNN tries to get that user's e-mail for something)
When I visit the site, my credentials are passed in (e.g. "MONORAIL\Administrator"). DNN asks the member provider if that's a valid user and it returns true. So it lets me into the sight. Now I only see the Home menu option because I haven't implemented a custom role provider yet.
Okay, so now I want to tell DNN that user has a role. The Roles table has two entries...
RoleName
-------------------------
Administrators
Registered Users
I'll pick the first as that should display the Admin menu option. And I'll just be quick and plug in a provider like this...
public class ADAMRoleProvider : RoleProvider
{
public override string[] GetRolesForUser(string name)
{
// HACK
if (name == @"MONORAIL\Administrator")
return new string[]{ "Administrators" };
However, that doesn't show the Admin menu option! Tracing the DNN code I see that it does ask my role provider for the list of roles my user has, but it doesn't use it. Security.vb compares the list of roles from my provider with what HttpContext has for "UserRoles". And "UserRoles" is empty! So the following method returns false...
Public Shared Function IsInRole(ByVal role As String) As Boolean
...
'Check with the Roles Provider
'to see if the user has the role
If objRoles.IsUserInRole(role) Then
'Now check with the DNN roles to see
'if the user has the role because
'the ExpiryDate may have passed
'for the user's role
Dim strRoles As String
strRoles = Convert.ToString(HttpContext.Current.Items("UserRoles"))
If strRoles.IndexOf(";" + role + ";") >= 0 Then
Return True
End If
End If
...
Return False
End Function
I'm wondering if this is a DNN bug or I haven't set up something correctly. I scanned for any code in DNN that sets "UserRoles". Its in Global.ascx.vb...
If Not Request.Cookies("portalroles") Is Nothing Then
' get roles from roles cookie
If Request.Cookies("portalroles").Value <> "" Then
Dim RoleTicket As FormsAuthenticationTicket = FormsAuthentication.Decrypt(Context.Request.Cookies("portalroles").Value)
Context.Items.Add("UserRoles", ";" + RoleTicket.UserData + ";")
Else
Context.Items.Add("UserRoles", "")
End If
Context.Items.Add("UserInfo", objUserInfo)
End If
When I trace it, I never enter this code and I'm not sure how I would since I'm not using Forms authentication or cookies.
Hmmmm, perhaps my role provider should set HttpContext's UserRoles? That doesn't seem right.