Files
archived-next-auth/www/docs/tutorials/ldap-auth.md
Igor Danchenko 0fae0c7a8e feat(provider): forward request to authorize (#1979)
* feat/add-request-to-credentials-authorize

* Update src/server/routes/callback.js

Co-authored-by: Balázs Orbán <info@balazsorban.com>

* Update types/providers.d.ts

Co-authored-by: Balázs Orbán <info@balazsorban.com>

* Update www/docs/providers/credentials.md

Co-authored-by: Balázs Orbán <info@balazsorban.com>

* Update www/docs

* Update test app

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2021-05-15 03:00:39 +02:00

2.6 KiB

id, title
id title
ldap-auth-example LDAP Authentication

NextAuth.js provides the ability to setup a custom Credential provider which we can take advantage of to authenticate users against an existing LDAP server.

You will need an additional dependency, ldapjs, which you can install by running npm install ldapjs.

Then you must setup the Providers.Credentials() provider key like so:

const ldap = require("ldapjs");
import NextAuth from "next-auth";
import Providers from "next-auth/providers";

export default NextAuth({
  providers: [
    Providers.Credentials({
      name: "LDAP",
      credentials: {
        username: { label: "DN", type: "text", placeholder: "" },
        password: { label: "Password", type: "password" },
      },
      async authorize(credentials, req) {
        // You might want to pull this call out so we're not making a new LDAP client on every login attemp
        const client = ldap.createClient({
          url: process.env.LDAP_URI,
        });

        // Essentially promisify the LDAPJS client.bind function
        return new Promise((resolve, reject) => {
          client.bind(credentials.username, credentials.password, (error) => {
            if (error) {
              console.error("Failed");
              reject();
            } else {
              console.log("Logged in");
              resolve({
                username: credentials.username,
                password: credentials.password,
              });
            }
          });
        });
      },
    }),
  ],
  callbacks: {
    async jwt(token, user, account, profile, isNewUser) {
      const isSignIn = user ? true : false;
      if (isSignIn) {
        token.username = user.username;
        token.password = user.password;
      }
      return token;
    },
    async session(session, user) {
      return { ...session, user: { username: user.username } };
    },
  },
  secret: process.env.NEXTAUTH_SECRET,
  jwt: {
    secret: process.env.NEXTAUTH_SECRET,
    encryption: true, // Very important to encrypt the JWT, otherwise you're leaking username+password into the browser
  },
});

The idea is that once one is authenticated with the LDAP server, one can pass through both the username/DN and password to the JWT stored in the browser.

This is then passed back to any API routes and retrieved as such:

token = await jwt.getToken({
	req,
	secret: process.env.NEXTAUTH_SECRET,
});
const {username, password} = token;

Thanks to Winwardo for the code example