Don't miss out Virtual Happy Hour this Friday (April 26).

Try our conversational search powered by Generative AI!

AD user login problems

Vote:
 

Hi!

I was asked to use the Active Directory for authorization of our intranet site. I'd done this before so I figured that it wouldn't take much to make it work. But aparently it does...

We are running an old intranet website with EpiServer v6, or something, and it's working with ldap/SSO, I'm creating a new intranet with EpiServer v11 where I want to use AD too. So I followed the documentation "Configuring Active Directory membership provider".

  • The firewall has the ports 389 and 445 open.
  • I used the AD account that was listed in the old intranet site, but this gave me an error so I used my own account instead. I testet my account in the application "Softerra LDAP Browser" and I can see the users and groups.
  • I added my user to the "ActiveDirectoryMembershipProvider->connectionUsername" without the domain and got an error that it couldn't login. So with the domain I assume it works.
  • I configured web.config -> membership and roleManager with MultiplexingRoleProvider

    <membership defaultProvider="MultiplexingMembershipProvider" userIsOnlineTimeWindow="10">
          <providers>
            <clear />
            <add name="MultiplexingMembershipProvider"
                type="EPiServer.Security.MultiplexingMembershipProvider, EPiServer.Framework.AspNet"
                provider1="SqlServerMembershipProvider"
                provider2="ActiveDirectoryMembershipProvider" />
            <add name="SqlServerMembershipProvider"
                type="System.Web.Security.SqlMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
                connectionStringName="EPiServerDB"
                requiresQuestionAndAnswer="false"
                applicationName="Intranett"
                requiresUniqueEmail="true"
                passwordFormat="Hashed"
                maxInvalidPasswordAttempts="5"
                minRequiredPasswordLength="7"
                minRequiredNonalphanumericCharacters="0"
                passwordAttemptWindow="10"
                passwordStrengthRegularExpression="" />
            <add name="ActiveDirectoryMembershipProvider"
                type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                connectionStringName="ActiveDirectoryProviderConnection"
                connectionUsername="[domain\user]"
                connectionPassword="[password]"
                enableSearchMethods="true"
                attributeMapUsername="sAMAccountName"
                connectionProtection="None"/>
          </providers>
        </membership>
        <roleManager enabled="true" defaultProvider="MultiplexingRoleProvider" cacheRolesInCookie="true">
          <providers>
            <clear />
            <add name="MultiplexingRoleProvider"
              type="EPiServer.Security.MultiplexingRoleProvider, EPiServer.Framework.AspNet"
              provider1="SqlServerRoleProvider"
              provider2="ActiveDirectoryRoleProvider"
              providerMap1="SqlServerMembershipProvider"
              providerMap2="ActiveDirectoryMembershipProvider" />
            <add name="SqlServerRoleProvider" connectionStringName="EPiServerDB" applicationName="Intranett" type="System.Web.Security.SqlRoleProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
            <add name="ActiveDirectoryRoleProvider"
               type="EPiServer.Security.ActiveDirectoryRoleProvider, EPiServer.Cms.AspNet" 
               connectionStringName="ActiveDirectoryProviderConnection"
               connectionUsername="[domain\user]"
               connectionPassword="[password]"
               enableSearchMethods="true"
               attributeMapUsername="sAMAccountName"
               connectionProtection="None"/>
          </providers>
        </roleManager>​


  • I add a connectionString

    <add name="ActiveDirectoryProviderConnection" connectionString="LDAP://domain/OU=xxx,OU=xxx,DC=xxx,DC=xxx"/>​
  • I added virtualRoles to map the groups from AD to Episerver groups for authorization.

Because it didn't work, I tried different configurations:

  • Only use the ActiveDirectoryProviders. I actually started with this and then changed to multiplex
  • Changed the connectionstring so it looks in a different OU and even without any OU, only DC.
  • Added the AD groups to the "<allow roles="" />" for both EPiServer and EPiServer/CMS/admin

The webserver has been connected to the domain, but no AD user has yet loggedin. I'm a local administrator on the webserver.

I'm not sure what to do next. I'm not an expert in c# nor EPiServer.

I've found some forum post here, suggesting to change:

  • IIS application pool identity
  • the query in EPiServer.Security.ActiveDirectoryRoleProvider -> FindUsersInRole because EpiServer uses * instead of % (or the other way around) in older versions. I can't imagine that this is still a problem... but maybe it is?

The latest thing I tried was to find out the roles (or groups) of the currently loggedin user (this is my own user) just to get some information on what is going on, and suddenly I got a list of all the groups my user is a member of in the AD... I figured that it has something to do with that the username in EPiServer is the same in the AD.

If you need more code examples or need more info, please just ask. I'm stuck at the moment.

Cheers Rob

#229372
Edited, Oct 13, 2020 12:53
Vote:
 

Hi Rob

Besides not logging you in to Episerver, does the site log or show any errors about the AD connection?

#229746
Oct 22, 2020 13:36
Vote:
 

Hi Stefan,

Thank you for your reply.

The only error I've got was when I changed the connectionUsername in the ActiveDirectoryMembershipProvider (and RoleProvider) so it just uses a username without the domain. Then I got an error saying it couldn't connect. Otherwise, nothing.

I talked with a colleague about the case and he suggested to login with ActiveDirectory that the site maybe needs a different loginform. I remember reading a forumpost that the standard loginform is hardcoded in startup.cs. Could this be the case?

#229784
Oct 23, 2020 7:20
Vote:
 

Your colleague mentioned the Startup.cs file? This implies another approach, called OWIN-based authentication.

Using this, you will then be redirecting the user to an AD FS page, instead of using the default login page (which "secretly" performs the authentication). But this is usually safer than replicating the authentication method from your old site.

The AD FS authentication is documented here.

If you cannot use this approach, let me know.

#229793
Oct 23, 2020 10:35
Vote:
 

No he didn't mentioned Startup.cs. He just suggested that EPiserver might need an other loginform for AD. Then I remembered reading a forumpost about the loginform being hard coded in Startup.cs, suggesting that this could be correct. This is why I was wondering if this was true.

The first step was actually to use ADFS. We tried it, but we didn't succeed. We don't have experience with ADFS and I'm not an expert with EPiServer. So there is a lot of trial-on-error being done :) Since this didn't worked, we thought it might be helpfull to first start with the normal AD connection (with membership- and roleprovider). But that didn't worked either... It feels to me that the documentation is lacking information. But maybe we are missing some important configuration settings or maybe I should know more stuff by default ;)

The latest status: I got help from an other colleague who has more experience with LDAP and ADFS, so we're back with the original plan. Using ADFS. We are now at the point that I'm being send back from the ADFS server to the site, but we stranded on the Rules in ADFS (I think). It seems that we're lacking some rules (for the claims) or we used the wrong rule to validate against. Because when I open [website]/episerver, I get an error saying the variable "username" can't be empty. We tried "Name" as the ClaimType, but it didn't worked. We couldn't find the right rule in ADFS to make it work. So now we use "NameIdentifier" and it doesn't give an error. But maybe it's the wrong one.

Sorry for the long story :)

#229802
Oct 23, 2020 13:25
Vote:
 

So did it work now, Rob?

Generally claim types consists of a namespace and a name, so "Name" is usually not enough.

If you can't see which claims are returned from AD FS, you can try setting a breakpoint in the SecurityTokenValidated delegate in the Startup class. Then you can inspect the returned claims and find the right claim type to use in the configuration.

#229803
Oct 23, 2020 13:50
Vote:
 

Hi Rob

How did you specify Name and NameIdentifier as the claim types?

In the Startup.cs file, you can add this piece of mapping to the AD FS middleware configuration. Then Episerver will read the claims and create local shadow users, accordingly.

TokenValidationParameters = new TokenValidationParameters
{
    NameClaimType = ClaimTypes.Upn, // or ClaimTypes.NameIdentifier
    RoleClaimType = ClaimTypes.Role
}
#229809
Oct 23, 2020 16:04
Vote:
 

Hi Stefan,

Thanks for your messages! But no it is not working.

Answer to your question, how did I specify Name and NameIdentifier as the claim types. I followed the documentation of Episerver, so I think it is this:

// Tell antiforgery to use the name claim
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;

We tried adding more rules in the ADFS server but that made it worse. Then I tried your suggestion by adding the TokenValidationParameters. But I didn't see any difference. 

At the moment I have other priorities, so I can't work on this right now. But I'll continue later. I'm thinking to ask for some professional help, since I don't have enough experience nor does our IT department :P

#229988
Oct 28, 2020 8:55
This thread is locked and should be used for reference only.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.