Code Monkey home page Code Monkey logo

identityserver4.ldapextension's Introduction

License Build status NuGet

IdentityServer4.LdapExtension

IdentityServer4 Ldap Extension (OpenLdap or ActiveDirectory).

Installation

The plugin is easy to install to your solution. Built using .Net Core 3.1 and .Net 5.0. The Nuget package can be installed by either searching the package IdentityServer.LdapExtension or by typing the following command in your package console:

Install-Package IdentityServer.LdapExtension

Be aware of the dependency with IdentityServer4. The version of the package is visible in your Visual Studio or through Nuget.org.

  • Ldap Extension 2.0.0 goes with IdentityServer 2.2.x
  • Ldap Extension 2.1.7 goes with IdentityServer 2.3.x
  • Ldap Extension 2.1.8 goes with IdentityServer 2.4.x
  • Ldap Extension 3.1.0 goes with IdentityServer 4.1.2

Configuration for IdentityServer4 Server

An easy extension method have been created in order to add the LDAP as a provider to your IdentityServer. For this you simply have to use the AddLdapUsers<TApplicationUser>(LdapConfigSection, StoreTypeOrCustomStore). The configuration has to be provided or it won't work. The configuration is described here.

In the Startup.cs under ConfigureServices method, you will have something similar to the following by default (Starter pack for IdentityServer). The last line is what you will need to add in order to get started.

// ... Code ...
services.AddIdentityServer(/*...*/)
  .AddInMemoryClients(Config.GetClients())                  // [LDAP API Example]
  .AddInMemoryIdentityResources(Config.IdentityResources()) // [LDAP API Example]
  .AddInMemoryApiScopes(Config.GetApiScope())               // [LDAP API Example]
  .AddInMemoryApiResources(Resources.ApiResources)
  .AddSigningCredential()
  /*...*/
  // [START of Usage of LDAP]
  .AddLdapUsers<OpenLdapAppUser>(_config.GetSection("IdentityServerLdap"), UserStore.InMemory)
  .AddProfileService<HostProfileService>() // Upgraded for LDAP (see code in project class for details).
  // [END of usage of LDAP]

Application User: 2 (OpenLdapAppUser, ActiveDirectoryAppUser) have been provided with this extension, but you can use your own as long as you implement the interface IAppUser. I encourage you to provide your own implementation. You might want to have claims/roles based on an active directory group or your attributes within LDAP are not the one I have defined.

Store types:

  1. UserStore.InMemory: Can be used when you test locally. It stores the logged in user in memory in order to avoid querying the LDAP server over and over. It is also used in order to store the external logged in user details (Google, Facebook, etc.).
  2. UserStore.Redis: Same as in memory, but is persisted and will be ready when you restart.
  3. ILdapUserStore implementation: Build your own store implementation and pass it as a parameter.

AppSettings Configuration

The appsettings.json will require a configuration for the extension. Here's an example using OpenLdap:

{
  "MyConfigurationSection": { // Name can be of your choosing
    "Url": "localhost",
    "Port": 389,
    "BindDn": "cn=ldap-ro,dc=contoso,dc=com",
    "BindCredentials": "P@ss1W0Rd!",
    "SearchBase": "ou=users,DC=contoso,dc=com",
    "SearchFilter": "(&(objectClass=posixAccount)(objectClass=person)(uid={0}))"
    // "Redis": "localhost:32771,ssl=false", // Required if using UserStore.Redis 
  }
}

If you want to see a working demo, you can open the implementation available the sample folder. It is based on the QuickStart from IdentityServer4 WebSite.

Multiple concurent Ldap (For different DN, or totally different Ldap)

In the case you would have a need to have multiple configuration to either connect to different LDAP servers or to even connect to different part of the directory (multiple area for the DN), this feature have been requested and it should be able to allow different type of AD to live together. The AAD is of course not part of this. In case you would like to use AAD, there's either other connector or you can also write your own.

The usage of multiple configuration will bring some issues, so here's the rules:

  1. Configurations needs to be all the same type, except if you have a custom LDapUser and you're not using the one provided in this extension.
  2. Rules for preFilterRegex can discriminate in order to not try on all the LDAP servers the credential/password for failure. It also avoid having some kind of DoS on all your servers in case of attack.
  3. If we have multiple LDAP configurations that are ok with the preFilterRegex, then the validation is done async (To be confirmed) and the first server to answer OK will be the one to use in order to get the information. The issue in that case is that it will try to call all your servers and that's probably not something you wish for.
  4. If it does not match anything, the extension will send back automatically a user not found.

By default the cache is using InMemory, but you can also use Redis. It needs to be set in the global configuration when multiple Ldap entries. This avoids having custom code for each Ldap.

Quick and Simple Example of a Configuration

2 configurations using a preFilterRegex for discrimination.

  "IdentityServerLdap": {
    // Example: If you use a redis instead of in-memory (See Startup.cs)
    //"redis": "localhost:32771,ssl=false",
    //"RefreshClaimsInSeconds": 3600,
    "Connections": [
      {
        "FriendlyName": "OpenLdap-Users",
        "Url": "localhost",
        "Port": 389,
        "Ssl": false,
        "BindDn": "cn=ldap-ro,dc=contoso,dc=com",
        "BindCredentials": "P@ss1W0Rd!",
        "SearchBase": "ou=users,DC=contoso,dc=com",
        "SearchFilter": "(&(objectClass=posixAccount)(objectClass=person)(uid={0}))",
        "PreFilterRegex": "^(?![a|A]).*$" // not mandatory and will take everything not starting with A
      },
      {
        "FriendlyName": "OpenLdap-BuzzUsers",
        "Url": "localhost",
        "Port": 389,
        "Ssl": false,
        "BindDn": "cn=ldap-ro,dc=contoso,dc=com",
        "BindCredentials": "P@ss1W0Rd!",
        "SearchBase": "ou=users-buzz,DC=contoso,dc=com",
        "SearchFilter": "(&(objectClass=posixAccount)(objectClass=person)(uid={0}))",
        "PreFilterRegex": "^([a|A]).*$" // not mandatory and will take everything not starting with A
      }
    ]
  }

In startup, the same as a single configuration. Basically the configuration section and nothing more. If it's a single configuration, it will upgrade the single configuration to act like a multi-configuration. It is recommended from now on to use the multi-configuration style. It's easier to handle the Redis and other new features if any comes.

You don't have an LDAP for your tests, use a OpenLdap docker image instead!

It's not a big problem. I wrote a small tutorial/article in order to setup an entire OpenLdap server within Docker in order to not pollute your PC and also to avoid relying on network administrator. That way you can play with existing users or create your own users directory. The tutorial/article is available at HoNoSoFt website.

Features in progress

I plan to work on the following:

  • Implement the SSL
  • Implement a cache invalidation based on time (After x time without being hit, remove from redis or from memory).

Contributors

Main contributor

  • @Nordes: The main author of the package (@me)

Special thanks to

  • @marianahycit: Contribution
  • @uchetfield: Contribution (Issue #10)
  • @ttutko
  • @chrgraefe

License

MIT

Regarding the IdentityServer4 Sample - Apache 2 (due to original code a bit updated)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.