November Happy Hour will be moved to Thursday December 5th.
November Happy Hour will be moved to Thursday December 5th.
Hi,
I haven't got a simple solution, but I've experienced the same situation and got it working.
What authentication mode are you using? If you're using "Windows" I think you should set the defaultProviders to "WindowsRoleProvider" and "WindowsMembershipProvider".
If you're using "Forms" you need to get the user to log on using the format "[user name]@[domain]"
My two cents.. someone smarter is welcome to explain how it's really done =)
Regards,
Peter
Hi Jonas!
Make sure that the ActiveDirectoryRoleProvider connects to the same AD node as the ActiveDirectoryMembershipProvider, as the ActiveDirectoryRoleProvider only looks for users contained in or _beneath_ the node it connects to (as specified in the ldap connection string).
So, if the ActiveDirectoryMembershipProvider is connected to a node "higher up" in the hierarchy it may authenticate users that the ActiveDirectoryRoleProvider will not be able to find.
Regards,
Johan Olofsson
Also note that the default attribute used to find user is 'userPrincipalName'.
The ActiveDirectoryMembershipProvider in your sample web.config specifies the attributeMapUsername to 'sAMAccountName', you would most likely want the same specified for the ActiveDirectoryRoleProvider.
/johan
Yes we are using windows authentication and if I change to WindowsMembershipProvider I can login without any problems.
But we need the functionality in the ActivDirectoryMembershipProvider because the customer has a large number of users and groups in the Active Directory.
/Jonas
What's the actual difference when using different defaultProviders? Isn't the ActiveDirectoryMembershipProvider loaded "anyway"? I.e. acts as a fall-back if WindowsMembership isn't able to confirm the user?
// Peter
No, only the provider specified as the "defaultProvider" will be used during authentication.
Thats the reason we came up with the MultiplexingProvider in EPiServerCMS5.
/johan
If I remove my domain name from my username "DOMAIN\username" -> "username" in the method "GetUsersInRole(userName)" then my user is found.
Is there any settings for changing the handling of username's with the Domain name included?
/Jonas
Did you try to set the attribute 'attributeMapUsername' for the ActiveDirectoryRoleProvider to have the same value, 'sAMAccountName' as specified for the ActiveDirectoryMembershipProvider.
Your earlier posted configurations implied that this attribute was left out for the roleprovider, which in that case woudl fallback to use the default 'userPrincipalName' attribute to locate user.
Regards,
johan
Yes, i have set the attributeMapUsername for both, but i it gives me the same result.
<roleManager enabled="true" defaultProvider="ActiveDirectoryRoleProvider" cacheRolesInCookie="true">
<providers>
<clear />
<add name="MultiplexingRoleProvider" type="EPiServer.Security.MultiplexingRoleProvider, EPiServer" provider1="SqlServerRoleProvider" provider2="WindowsRoleProvider" providerMap1="SqlServermembershipProvider" providerMap2="WindowsMembershipProvider" />
<add name="WindowsRoleProvider" applicationName="EPiServerSample" type="EPiServer.Security.WindowsRoleProvider, EPiServer" />
<add name="SqlServerRoleProvider" connectionStringName="EPiServerDB" applicationName="EPiServerSample" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add name="ActiveDirectoryRoleProvider"
type="EPiServer.Security.ActiveDirectoryRoleProvider, EPiServer.Templates.Public"
connectionStringName="ActiveDirectoryProviderConnection"
connectionUsername="xx"
connectionPassword="xx"
attributeMapUsername="sAMAccountName"/></providers>
</roleManager>
<membership defaultProvider="ActiveDirectoryMembershipProvider" userIsOnlineTimeWindow="10">
<providers>
<clear />
<add name="MultiplexingMembershipProvider" type="EPiServer.Security.MultiplexingMembershipProvider, EPiServer" provider1="SqlServerMembershipProvider" provider2="WindowsMembershipProvider" />
<add name="WindowsMembershipProvider" type="EPiServer.Security.WindowsMembershipProvider, EPiServer" deletePrefix="BUILTIN\" searchByEmail="true" />
<add name="SqlServerMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="EPiServerDB" requiresQuestionAndAnswer="false" applicationName="EPiServerSample" requiresUniqueEmail="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />
<add name="ActiveDirectoryMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ActiveDirectoryProviderConnection"
connectionUsername="xx"
connectionPassword="xx"
enableSearchMethods="true"
attributeMapUsername="sAMAccountName"/></providers>
</membership>
Ok, I can now reproduce the same error, the key factor here is that the membershipprovider does take some extra steps to conform the passed in username depending on wether the userPrincipalName or sAMAccountName attribute are to be used to query the user, whereas the roleprovider simply uses the passed in username "as is" without any modifications.
And, when using WindowsAuthentication, the Domain/ will always prefix the username, so the roleprovider will query for "(sAMAccountName=DOMAIN\user)" whereas the membershipprovider will do a "(sAMAccountName=user)".
The solution would of course be to have the roleprovider determine if it too needs to take these extra steps to massage the username into its expected format before using it in the directory query.
I'll continue to investigate this a little further to see if we can come up with some quick and elegant solution.
/johan
Ehum, a little further investigation reveals that the ActiveDirectoryMembershipProvider isn't involved at all up until the point where the roleprovider gets called in its GetRolesForUser() method ... (!)
(The above only applies to when Windows authentication is used)
And, you do get the exact same error (null returned) if you were to try to call the ActiveDirectoryMembershipProvider.GetUser(userName) with the username in the form "DOMAIN\user".
So, I guess the solution would be to extract the username from the DOMAIN\username ´, and then just pass it on to the query.
To get the membership to work as well, youd have to write a custom membershipprovider and derive it from the ActiveDirectoryMembershipProvider, then override the necessare methods where a userName is passed and perform the same DOMAIN extraction before passing on to the base implementation.
/johan
Ok, but what's the difference between using windows authentication in EPiServer CMS4 and configure the EPsLdapXXX settings in web.config (Using a Windows 2003 Active Directiry) (as we did in the version 4 site that we now upgrading to version 5), and using the WindowsMembership and WindowsRoleProvider in EPiServer CMS?
(We can get all AD groups in the permission dialogs and so on with the WindowsRole / Membership provider)
Need to know if I should spend more time on the ActiveDirectoryMembershipProvider.
One other strange problem is that the permissions in the page tree doesn't work after upgraded to version5, i needed to reset all permission (Save permissions recrusive) in the page tree before it worked.
(The groups and permissions was shown in the permission dialog but they didn't work with my user)
This is a problem because we have a lot of different permissions in the sub levels of the page tree.
/Jonas
Well, the EPiServer4's code for querying the AD did just exactly such a "normalization" (removing the DOMAIN-part) of the logged on username before running the query on the username.
This was done in the method DetermineDistinguishedNameFromLogonName() on the LdapConnection type found in the Ldapper.dll assembly.
When all that proprietary code was dropped in EPIServerCMS5 (in favour of the Asp.Net Membership/Role-architecture), you will have to add the functionality yourself, possibly "on top" of the existing providers.
/johan
I'm having some problem to get the ActiveDirectoryRoleProvider to work.
When I access the site I get an error message: (The account exists in the AD)
2008-08-29 14:21:35,021 ERROR [7] EPiServer.Global.Global_Error - 1.2.5 Unhandled exception in ASP.NET
System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.Configuration.Provider.ProviderException: The user DOMAIN\username does not exist.
at EPiServer.Security.ActiveDirectoryRoleProvider.GetRolesForUser(String username) in C:\Inetpub\EPiServerCMS5\security\ActiveDirectoryRoleProvider.cs:line 200
Configuration
The user used to access the AD has the required permissions.
<roleManager enabled="true" defaultProvider="ActiveDirectoryRoleProvider" cacheRolesInCookie="true">
<providers>
<clear />
<add name="MultiplexingRoleProvider" type="EPiServer.Security.MultiplexingRoleProvider, EPiServer" provider1="SqlServerRoleProvider" provider2="WindowsRoleProvider" providerMap1="SqlServermembershipProvider" providerMap2="WindowsMembershipProvider" />
<add name="WindowsRoleProvider" applicationName="EPiServerSample" type="EPiServer.Security.WindowsRoleProvider, EPiServer" />
<add name="SqlServerRoleProvider" connectionStringName="EPiServerDB" applicationName="EPiServerSample" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add name="ActiveDirectoryRoleProvider"
type="EPiServer.Security.ActiveDirectoryRoleProvider, EPiServer.Templates.Public"
connectionStringName="ActiveDirectoryProviderConnection"
connectionUsername="xx"
connectionPassword="xx"/>
</providers>
</roleManager>
<membership defaultProvider="ActiveDirectoryMembershipProvider" userIsOnlineTimeWindow="10">
<providers>
<clear />
<add name="MultiplexingMembershipProvider" type="EPiServer.Security.MultiplexingMembershipProvider, EPiServer" provider1="SqlServerMembershipProvider" provider2="WindowsMembershipProvider" />
<add name="WindowsMembershipProvider" type="EPiServer.Security.WindowsMembershipProvider, EPiServer" deletePrefix="BUILTIN\" searchByEmail="true" />
<add name="SqlServerMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="EPiServerDB" requiresQuestionAndAnswer="false" applicationName="EPiServerSample" requiresUniqueEmail="true" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="7" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" />
<add name="ActiveDirectoryMembershipProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web,
Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
connectionStringName="ActiveDirectoryProviderConnection"
connectionUsername="xx"
connectionPassword="xx"
enableSearchMethods="true" attributeMapUserName="sAMAccountName"/>
</providers>