title: How to do LDAP authentication in flask restful
body: <p>I need to create LDAP Authentication for a Rest API used within the network of an organization.</p>
  <p>I thought I might be able to do this, creating an <code>AuthUtility</code> class :</p>
  <pre><code>class AuthUtility:
      def __init__(self, user_model, user_data):
          self.username = user_model.username
          self.password = user_model.password
          self.parsed_username = user_data.username
          self.parsed_password = user_data.password
          self.parsed_auth_method = user_data.auth_method
  
      def _is_ldap_authenticated(self) -&gt; bool:
          # TODO: To be replaced by ldap authentication
          return False # Hard-Coded
  
      def _is_db_authenticated(self) -&gt; bool:
          return self.password == self.parsed_password
  
      def is_authenticated(self) -&gt; bool:
          auth_method = self.parsed_auth_method
          if auth_method == &quot;ldap&quot;:
              return self._is_ldap_authenticated()
          elif auth_method == &quot;db&quot;:
              return self._is_db_authenticated()
          else:
              # This should never happen
              print(f&quot;Method {auth_method} not defined!&quot;)
              # TODO: Return error! This should never happen!
              return False
  
  
  class UserModel(db.Model):
      __tablename__ = &quot;users&quot;
  
      id = db.Column(db.Integer, primary_key=True)
      username = db.Column(db.String(80), nullable=False)
      password = db.Column(db.String(80), nullable=False)
  
      @classmethod
      def find_all(cls) -&gt; List[&quot;UserModel&quot;]:
          return cls.query.all()
  
      @classmethod
      def find_by_username(cls, username: str) -&gt; &quot;UserModel&quot;:
          return cls.query.filter_by(username=username).first()
  
      @classmethod
      def find_by_id(cls, _id: int) -&gt; &quot;UserModel&quot;:
          return cls.query.filter_by(id=_id).first()
  
      def save_to_db(self) -&gt; None:
          db.session.add(self)
          db.session.commit()
  
      def delete_from_db(self) -&gt; None:
          db.session.delete(self)
          db.session.commit()
  
  </code></pre>
  <p>And in my post request to the login endpoint, include a key <code>auth_method</code> whose value can be either <code>ldap</code> or <code>db</code></p>
  <pre><code>BODY:
  {
      &quot;username&quot;: &quot;myusername&quot;,
      &quot;password&quot;: &quot;mypassword&quot;, 
      &quot;auth_method&quot;: &quot;db&quot;
  }
  </code></pre>
  <p>or</p>
  <pre><code>BODY:
  {
      &quot;username&quot;: &quot;myusername&quot;,
      &quot;password&quot;: &quot;mypassword&quot;, 
      &quot;auth_method&quot;: &quot;ldap&quot;
  }
  </code></pre>
  <pre><code>class UserLogin(Resource):
      @classmethod
      def post(cls):
          request_json = request.get_json()
          # Pop auth_method from request_json
          try:
              auth_method = request_json.pop(&quot;auth_method&quot;)
          except KeyError:
              return {&quot;message&quot;: &quot;Authentication method should be defined&quot;}
  
          user_data = user_schema.load(request_json)
          # Find user in the database
          user = UserModel.find_by_username(user_data.username)
          # Add back auth_method
          user_data.auth_method = auth_method
  
          # Check if the user with username exist in the database
          if not user:
              return {&quot;message&quot;: &quot;user_user_not_found&quot;}, 401
          # Check to see the user is authenticated
          elif not AuthUtility(user, user_data).is_authenticated():
              return {&quot;message&quot;: &quot;user_invalid_credentials&quot;}, 401
  
          # Create and return access_token and refresh_token
          access_token = create_access_token(user.id, fresh=True)
          refresh_token = create_refresh_token(user.id)
          return {&quot;access_token&quot;: access_token, &quot;refresh_token&quot;: refresh_token}, 200
  </code></pre>
  <p>The user can log in through either <code>db</code> or <code>ldap</code> <code>auth_method</code>s.</p>
  <p><code>db</code> is clear to me but I do not know how to do it with <code>ldap</code>.</p>
  <p>Any idea how to actually complete it and actually using it in production?</p>
  <p>I also have found some python ldap3 library but really not sure how to use it</p>
  <p>I need to write this part:</p>
  <pre><code>def _is_ldap_authenticated(self) -&gt; bool:
      # TODO: To be replaced by ldap authentication
      return False # Hard-Coded
  </code></pre>
  <p>But the question is, how and is there any resource available I can use and see how to do it?</p>
  <p>To add some detail about <code>ldap</code>, please note that I have done this test and it connects:</p>
  <pre><code>from ldap3 import SAFE_SYNC, Server, Connection, ALL
  
  ldsp_server = &quot;ldap://***.***.com&quot;
  root_dn = &quot;dc=***,dc=com&quot;
  ldap_user_name = &quot;***&quot;
  ldap_password = &quot;***&quot;
  
  
  def ldap_test():
  
      server = Server(ldsp_server, get_info=ALL)
      conn = Connection(
          server,
          user=ldap_user_name,
          password=ldap_password,
          client_strategy=SAFE_SYNC,
          auto_bind=True,
      )
  </code></pre>