From 8c6a9cbcf966c8d6d38f65cd3dc8095543ad9270 Mon Sep 17 00:00:00 2001 From: "B. Stack" Date: Fri, 25 Jun 2021 11:16:43 -0400 Subject: now store user groups in session, for display --- session_app.py.publish | 64 ++++++++++++++++++++++++++++++++++++-------------- session_ldap.py | 36 ++++++++++++++++++---------- templates/view.html | 5 +++- 3 files changed, 73 insertions(+), 32 deletions(-) diff --git a/session_app.py.publish b/session_app.py.publish index ac37e17..18bf5f1 100755 --- a/session_app.py.publish +++ b/session_app.py.publish @@ -97,16 +97,34 @@ def requires_authn_kerberos(function): # if ldap config options are set, then do kerberos -> short username resolution user = ctx.kerberos_user if 'LDAP_USER_KERBEROS_PRINCIPAL_ATTRIB' in app.config: - user = session_ldap.get_ldap_attrib_from_krbPrincipalName( + conn = session_ldap.get_ldap_connection( server_uri=get_next_ldap_server(app), bind_dn=app.config['LDAP_BIND_DN'], bind_pw=app.config['LDAP_BIND_PASSWORD'], + ) + this_user = session_ldap.get_ldap_attrib_from_krbPrincipalName( + connection = conn, search_base=app.config['LDAP_USER_BASE'], - user_attrib=app.config['LDAP_USER_DISPLAY_ATTRIB'], + user_attrib="dn", user_krbPrincipalName=user, krbPrincipalName_attrib=app.config['LDAP_USER_KERBEROS_PRINCIPAL_ATTRIB'] ) - response = function(user, *args, **kwargs) + #print(f"DEBUG: krb user {user} is ldap dn {this_user}") + shortuser = session_ldap.get_ldap_username_attrib_from_dn( + authenticated_user=conn, + user_dn=this_user, + user_match_attrib=app.config['LDAP_USER_DISPLAY_ATTRIB'] + ) + #print(f"DEBUG: shortuser {shortuser}") + groups = session_ldap.get_ldap_user_groups( + connection=conn, + user_dn=this_user, + user_attrib_memberof=app.config['LDAP_USER_ATTRIB_MEMBEROF'], + group_name_attrib=app.config['LDAP_GROUP_NAME_ATTRIB'], + group_base=app.config['LDAP_GROUP_BASE'] + ) + #print(f"DEBUG: groups {groups}") + response = function(shortuser, groups, *args, **kwargs) response = make_response(response) if ctx.kerberos_token is not None: response.headers['WWW-Authenticate'] = ' '.join(['negotiate', ctx.kerberos_token]) @@ -131,7 +149,7 @@ def requires_authn_ldap(function): # formdata is in session if we are coming from login_basic() form = session.get('formdata', None) if form: - print(f"DEBUG: requires_authn_ldap form={form}") + #print(f"DEBUG: requires_authn_ldap form={form}") session.pop('formdata') if 'username' in form: username = form['username'] @@ -156,7 +174,7 @@ def requires_authn_ldap(function): ) # list_matching_users always returns list, so if it contains <> 1 we are in trouble if len(this_user) != 1: - print(f"WARNING: cannot determine unique user for {app.config['LDAP_USER_MATCH_ATTRIB']}={username} which returned {tihs_user}") + print(f"WARNING: cannot determine unique user for {app.config['LDAP_USER_MATCH_ATTRIB']}={username} which returned {this_user}") return _unauthorized_ldap() this_user = this_user[0] print(f"DEBUG: requires_authn_ldap: found in ldap the username {this_user}") @@ -166,7 +184,15 @@ def requires_authn_ldap(function): authenticated_user=ll, user_match_attrib=app.config['LDAP_USER_DISPLAY_ATTRIB'] ) - return function(shortuser,*args, **kwargs) + groups = session_ldap.get_ldap_user_groups( + connection=ll, + user_dn=this_user, + user_attrib_memberof=app.config['LDAP_USER_ATTRIB_MEMBEROF'], + group_name_attrib=app.config['LDAP_GROUP_NAME_ATTRIB'], + group_base=app.config['LDAP_GROUP_BASE'] + ) + print(f"DEBUG: user {shortuser} has groups {groups}") + return function(shortuser, groups ,*args, **kwargs) else: return _unauthorized_ldap() return decorated @@ -193,9 +219,10 @@ def protected_page(): def protected_page_real(): s_user = session['user'] c_user = request.cookies.get('user') + groups = session['groups'] cookie=request.cookies print(cookie) - return render_template('view.html', c_user = c_user, s_user=s_user, cookie=cookie) + return render_template('view.html', c_user = c_user, s_user=s_user, cookie=cookie, groups=groups) @app.route("/login/new") @app.route("/login/new/") @@ -257,11 +284,20 @@ def ldap_login(username,password): @app.route("/login/kerberos") @app.route("/login/kerberos/") @requires_authn_kerberos -def login_kerberos(user): +def login_kerberos(user,groups=[]): resp = Response(f'success with kerberos') #resp.headers['login'] = "from-kerberos" resp.set_cookie('type',"kerberos") - resp = login_generic(session,resp,user,None) + resp = login_generic(session,resp,user,groups) + return resp + +@app.route("/login/ldap", methods=['POST','GET']) +@app.route("/login/ldap/", methods=['POST','GET']) +@requires_authn_ldap +def login_ldap(user,groups=[]): + resp = Response(f'success with ldap') + resp.set_cookie('type',"ldap") + resp = login_generic(session,resp,user,groups) return resp def login_generic(session,resp,user,groups=[]): @@ -272,15 +308,7 @@ def login_generic(session,resp,user,groups=[]): session.permanent = True session['user']=user session['end_time'] = end_time_str - return resp - -@app.route("/login/ldap", methods=['POST','GET']) -@app.route("/login/ldap/", methods=['POST','GET']) -@requires_authn_ldap -def login_ldap(user,groups=[]): - resp = Response(f'success with ldap') - resp.set_cookie('type',"ldap") - resp = login_generic(session,resp,user,groups) + session['groups'] = groups return resp @app.route("/login/form", methods=['POST','GET']) diff --git a/session_ldap.py b/session_ldap.py index 1b2dc12..b60bc8b 100644 --- a/session_ldap.py +++ b/session_ldap.py @@ -8,13 +8,22 @@ import ldap3 from ldap3.core.exceptions import LDAPBindError, LDAPPasswordIsMandatoryError -def list_matching_users(server_uri, bind_dn, bind_pw,user_base, username, user_match_attrib): - search_filter=f"({user_match_attrib}={username})" +def get_ldap_connection(server_uri, bind_dn, bind_pw): server = ldap3.Server(server_uri) conn = ldap3.Connection(server, auto_bind=True,user=bind_dn, password=bind_pw) + return conn + +def list_matching_users(server_uri= "", bind_dn = "", bind_pw = "", connection = None, user_base = "", username = "", user_match_attrib = ""): + search_filter=f"({user_match_attrib}={username})" + if connection and isinstance(connection, ldap3.core.connection.Connection): + conn = connection + else: + conn = get_ldap_connection(server_uri, bind_dn, bind_pw) conn.search( search_base=user_base, - search_filter=search_filter) + search_filter=search_filter, + search_scope="SUBTREE" + ) print(f"DEBUG: search_base {user_base}") print(f"DEBUG: search_filter {search_filter}") result = [] @@ -27,8 +36,7 @@ def authenticated_user(server_uri, user_dn, password): print(f"server_uri: {server_uri}") print(f"user_dn: {user_dn}") try: - server = ldap3.Server(server_uri) - conn = ldap3.Connection(server, auto_bind=True, user=user_dn, password=password) + conn = get_ldap_connection(server_uri, user_dn, password) return conn except LDAPBindError as e: if 'invalidCredentials' in str(e): @@ -61,9 +69,12 @@ def list_ldap_servers_for_domain(domain): namelist.append(domain) return namelist -def get_ldap_user_groups(server_uri, bind_dn, bind_pw,user_dn,user_attrib_memberof,group_name_attrib,group_base): - server = ldap3.Server(server_uri) - conn = ldap3.Connection(server, auto_bind=True,user=bind_dn, password=bind_pw) +def get_ldap_user_groups(server_uri = "", bind_dn = "", bind_pw = "", connection = None, user_dn = "", user_attrib_memberof = "memberof", group_name_attrib = "uid", group_base = ""): + if connection and isinstance(connection, ldap3.core.connection.Connection): + conn = connection + else: + conn = get_ldap_connection(server_uri, bind_dn, bind_pw) + # so now we have a connection conn.search( search_base=user_dn, search_filter="(cn=*)", # this has the potential to not work in a directory where CN is not a part of any dn? @@ -97,8 +108,7 @@ def get_ldap_attrib_from_krbPrincipalName(server_uri = None, bind_dn = "", bind_ if connection and isinstance(connection, ldap3.core.connection.Connection): conn = connection else: - server = ldap3.Server(server_uri) - conn = ldap3.Connection(server, auto_bind=True,user=bind_dn, password=bind_pw) + conn = get_ldap_connection(server_uri, bind_dn, bind_pw) conn.search( search_base=search_base, search_scope="SUBTREE", @@ -111,15 +121,15 @@ def get_ldap_attrib_from_krbPrincipalName(server_uri = None, bind_dn = "", bind_ else: return entry.entry_attributes_as_dict[entry.entry_attributes[0]][0] -def get_ldap_username_attrib_from_dn(server_uri = None, bind_dn = "", bind_pw = "", authenticated_user = None, user_match_attrib = "dn", user_dn = None): +def get_ldap_username_attrib_from_dn(server_uri = None, bind_dn = "", bind_pw = "", authenticated_user = None, user_match_attrib = "dn", user_dn = ""): # Needs (server_uri, bind_dn, bind_pw, user_dn) or (authenticated_user) if authenticated_user and isinstance(authenticated_user, ldap3.core.connection.Connection): conn = authenticated_user search_base=authenticated_user.extend.standard.who_am_i().replace("dn: ","") else: # then we have to use a new connection - server = ldap3.Server(server_uri) - conn = ldap3.Connection(server, auto_bind=True,user=bind_dn, password=bind_pw) + conn = get_ldap_connection(server_uri, bind_dn, bind_pw) + if user_dn: search_base=user_dn, # so now conn is the connection regardless of how we got there, and search_base #print(f"DEBUG: search_base {search_base} attributes {user_match_attrib}") diff --git a/templates/view.html b/templates/view.html index 5c14175..0496cae 100644 --- a/templates/view.html +++ b/templates/view.html @@ -5,5 +5,8 @@ Cookie user: {{ c_user }}
Session: {{ session }}
Cookies: {{ cookie }}
#} Session expires: {{ cookie.timestamp }}
-Logged in through: {{ cookie.type }} +Logged in through: {{ cookie.type }}{% if groups %}
+Usergroups:{% endif %} -- cgit