# encoding: utf8
from ldap3 import Server, Connection, ALL, SUBTREE, ServerPool
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField
from wtforms.validators import InputRequired
from .. import db
from flask import current_app
class TmpUser(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(100))
def __init__(self, username, password):
self.username = username
@staticmethod
def try_ldap_login(username, password):
"""
ldap 认证,
参考:https://blog.csdn.net/ns2250225/article/details/79217285
https://code.tutsplus.com/tutorials/flask-authentication-with-ldap--cms-23101
:param username:
:param password:
:return:
"""
userdn = username + current_app.config['LDAP_USERDN_POSTFIX']
server = ServerPool(current_app.config['LDAP_SERVER'])
conn = Connection(server, user=userdn, password=password, check_names=True, lazy=False,
raise_exceptions=False)
# app.logger.debug(conn)
return conn.bind()
def is_authenticated(self):
return True
def is_active(self):
return True
def is_anonymous(self):
return False
def get_id(self):
return str(self.id)
class LoginForm(FlaskForm):
username = StringField('Username', [InputRequired()])
password = PasswordField('Password', [InputRequired()])
views/auth.py
# encoding: utf8
from flask_mako import render_template
from ..models.auth import TmpUser, LoginForm
from flask import request, redirect, \
url_for, Blueprint, current_app
from flask_login import current_user, login_user, \
logout_user, login_required
from .. import login_manager, db
auth_bp = Blueprint('auth', __name__, url_prefix='/engine/auth')
@login_manager.user_loader
def load_user(id):
return TmpUser.query.get(int(id))
#
# @auth_bp.before_request
# def get_current_user():
# g.user = current_user
@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return redirect(url_for('index_bp.index'))
form = LoginForm(request.form)
form.next = request.args.get('next') or '' # 登录成功后跳转回原来的url
if request.method == 'POST' and form.validate():
username = request.form.get('username')
password = request.form.get('password')
res = TmpUser.try_ldap_login(username, password)
if not res:
current_app.logger.error('ldap login failed')
return render_template('login.html', form=form)
user = TmpUser.query.filter_by(username=username).first()
if not user:
user = TmpUser(username, password)
db.session.add(user)
db.session.commit()
login_user(user)
return redirect(request.args.get('next') or url_for('index_bp.index'))
if form.errors:
current_app.logger.error('login form error')
return render_template('login.html', form=form)
@auth_bp.route('/logout')
@login_required
def logout():
current_app.logger.debug('log out .....')
logout_user()
return redirect(url_for('index_bp.index'))
login.html
<%inherit file="index.html"/>
<%def name="bodyContent()">
<div class="top-pad">
ldap login:
<form method="POST"
action="${ url_for('auth.login') }?next=${form.next}"
role="form">
${ form.csrf_token }
<div class="form-group">${ form.username.label }: ${ form.username() }</div>
<div class="form-group">${ form.password.label }: ${ form.password() }</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</%def>