auth with ldap

This commit is contained in:
pycook 2020-04-01 20:30:44 +08:00
parent 486fcac138
commit ba2a6a65b5
6 changed files with 39 additions and 2 deletions

View File

@ -25,6 +25,7 @@ supervisor = "==4.0.3"
Flask-Login = "==0.4.1" Flask-Login = "==0.4.1"
Flask-Bcrypt = "==0.7.1" Flask-Bcrypt = "==0.7.1"
Flask-Cors = ">=3.0.8" Flask-Cors = ">=3.0.8"
python-ldap = "==3.2.0"
# Caching # Caching
Flask-Caching = ">=1.0.0" Flask-Caching = ">=1.0.0"
# Environment variable parsing # Environment variable parsing

View File

@ -13,8 +13,8 @@ from flask import request
from flask import session from flask import session
from flask_login import login_user from flask_login import login_user
from api.models.acl import User
from api.lib.perm.acl.cache import UserCache from api.lib.perm.acl.cache import UserCache
from api.models.acl import User
def _auth_with_key(): def _auth_with_key():

View File

@ -5,6 +5,7 @@ import copy
import hashlib import hashlib
from datetime import datetime from datetime import datetime
import ldap
from flask import current_app from flask import current_app
from flask_sqlalchemy import BaseQuery from flask_sqlalchemy import BaseQuery
@ -50,6 +51,32 @@ class UserQuery(BaseQuery):
return user, authenticated return user, authenticated
def authenticate_with_ldap(self, username, password):
ldap_conn = ldap.initialize(current_app.config.get('LDAP_SERVER'))
ldap_conn.protocol_version = 3
ldap_conn.set_option(ldap.OPT_REFERRALS, 0)
if '@' in username:
who = '{0}@{1}'.format(username.split('@')[0], current_app.config.get('LDAP_DOMAIN'))
else:
who = '{0}@{1}'.format(username, current_app.config.get('LDAP_DOMAIN'))
username = username.split('@')[0]
user = self.get_by_username(username)
try:
if not password:
raise ldap.INVALID_CREDENTIALS
ldap_conn.simple_bind_s(who, password)
if not user:
from api.lib.perm.acl.user import UserCRUD
user = UserCRUD.add(username=username, email=who)
return user, True
except ldap.INVALID_CREDENTIALS:
return user, False
def search(self, key): def search(self, key):
query = self.filter(db.or_(User.email == key, query = self.filter(db.or_(User.email == key,
User.nickname.ilike('%' + key + '%'), User.nickname.ilike('%' + key + '%'),

View File

@ -26,7 +26,10 @@ class LoginView(APIView):
def post(self): def post(self):
username = request.values.get("username") or request.values.get("email") username = request.values.get("username") or request.values.get("email")
password = request.values.get("password") password = request.values.get("password")
user, authenticated = User.query.authenticate(username, password) if current_app.config.get('AUTH_WITH_LDAP'):
user, authenticated = User.query.authenticate_with_ldap(username, password)
else:
user, authenticated = User.query.authenticate(username, password)
if not user: if not user:
return abort(403, "User <{0}> does not exist".format(username)) return abort(403, "User <{0}> does not exist".format(username))
if not authenticated: if not authenticated:

View File

@ -20,6 +20,7 @@ supervisor == 4.0.3
Flask-Login == 0.4.1 Flask-Login == 0.4.1
Flask-Bcrypt == 0.7.1 Flask-Bcrypt == 0.7.1
Flask-Cors >= 3.0.8 Flask-Cors >= 3.0.8
python-ldap == 3.2.0
# Caching # Caching
Flask-Caching >= 1.0.0 Flask-Caching >= 1.0.0
# Environment variable parsing # Environment variable parsing

View File

@ -69,6 +69,11 @@ CAS_VALIDATE_ROUTE = "/cas/serviceValidate"
CAS_AFTER_LOGIN = "/" CAS_AFTER_LOGIN = "/"
DEFAULT_SERVICE = "http://127.0.0.1:8000" DEFAULT_SERVICE = "http://127.0.0.1:8000"
# # ldap
AUTH_WITH_LDAP = False
LDAP_SERVER = ''
LDAP_DOMAIN = ''
# # pagination # # pagination
DEFAULT_PAGE_COUNT = 50 DEFAULT_PAGE_COUNT = 50