2020年5月9日 星期六

[ASP.NET Core] Identity Server 4 – Authenticate by multiple LDAP


 ASP.NET Core   Identity Server 4   Multiple LDAP  


Introduction






Here is an example of how to authenticate with multiple LDAP servers by Nordes/IdentityServer4.LdapExtension.

Restriction and notes:

·         The LDAP servers must be as the same type, e.q. we cannot authenticate with OpenLDAP and Microsoft AD server in the same time.
·         The authentication will try all the LDAP servers, in the order of configuration, until the first one says okay. (However, we can use the option: “PreFilterRegex”, to filter which LDAP to authenticate by regex on user-name.










Environment


Docker 18.05.0-ce
ASP.NET Core 3.0.201
IdentityServer4 3.1.2
IdentityModel 4.0.0



Implement


The source code is on my Github.

Prepare 2 OpenLDAP containers

First run 2 OpenLDAP containers,

$ docker run -e LDAP_ADMIN_PASSWORD=admin -d  -p 380:389 -p 636:636 --name openldap-demo1 osixia/openldap:1.2.4
$ docker run -e LDAP_ADMIN_PASSWORD=admin -d  -p 390:389 -p 637:636 --name openldap-demo2 osixia/openldap:1.2.4


Then add a user “demo1.user” to openldap-demo1:





And add a user “demo2.user” to openldap-demo2:




Update configuration

appsettings.json

Put the multiple LDAP server’s settings inside “Connections”,

"XXXXX": {
    "Connections": [
      {
        // openldap-demo1 settings
      },
      {
        // openldap-demo2 settings
      }
    ]
  },


For example, (see source code)

{
  "Logging": {
    "LogLevel": {
      "Default""Debug",
      "System""Information",
      "Microsoft""Information"
    }
  },
  "LdapServer": {
    "Connections": [
      {
        "FriendlyName""OpenLdap-demo1",
        "Url""localhost",
        "Port"389,
        "Ssl"false,
        "BindDn""cn=admin,dc=example,dc=org",
        "BindCredentials""admin",
        "SearchBase""dc=example,dc=org",
        "SearchFilter""(&(objectClass=person)(uid={0}))",
        "PreFilterRegex""^(?!demo2.).*$"
      },
      {
        "FriendlyName""OpenLdap-demo2",
        "Url""localhost",
        "Port"390,
        "Ssl"false,
        "BindDn""cn=admin,dc=example,dc=org",
        "BindCredentials""admin",
        "SearchBase""dc=example,dc=org",
        "SearchFilter""(&(objectClass=person)(uid={0}))",
        "PreFilterRegex""^(?!demo1.).*$"
      }
    ]
  }
}



I set regex rules on “PreFilterRegex” option to allow only matched user-name to be authenticated on the LDAP,

LDAP
PreFilterRegex
Authenticate when
OpenLdap-demo1
^(?!demo2.).*$
User name does not start with “demo2.”.
E.q. “demo1.peter”, “peter” will be authenticated, but “demo2.peter” won’t.
OpenLdap-demo2
^(?!demo1.).*$
User name does not start with “demo1.”.
E.q. “demo2.peter”, “peter” will be authenticated, but “demo1.peter” won’t.







Startup.cs:ConfigureServices


Make sure that we are injecting the service with OpenLdapAppUser model.

public void ConfigureServices(IServiceCollection services)
{
            services.AddControllers()
                 .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);

            var builder = services.AddIdentityServer();

            // … skip

            builder.AddLdapUsers<OpenLdapAppUser>(this.configuration.GetSection("LdapServer"), UserStore.InMemory); // OpenLDAP
            //builder.AddLdapUsers<ActiveDirectoryAppUser>(this.configuration.GetSection("LdapServer"), UserStore.InMemory); // ActiveDirectory

}



Now we can authenticate both "demo1.user" and "demo2.user" successfully.



  



Source Code




Reference








沒有留言:

張貼留言