pythonauthenticationldapapache-supersetflask-appbuilder

Reuse the credentials of one system to Log in to another


I'm new to Flask, I'm using the apache-superset in version 0.38.0.

In it I'm using an LDAP authentication method, everything is functional.

However, I have another system in the company, which also uses LDAP to login, proprietary system. The idea is that when the user is logged in to our system and is going to enter the superset, he is already logged in, taking advantage of the credentials used in our system, since both are use LDAP.

What I've found so far: Apparently this is the class that authenticates LDAP credentials:

class AuthLDAPView(AuthView):
    login_template = "appbuilder/general/security/login_ldap.html"

    @expose("/login/", methods=["GET", "POST"])
    def login(self):
        if g.user is not None and g.user.is_authenticated:
            return redirect(self.appbuilder.get_url_for_index)
        form = LoginForm_db()
        if form.validate_on_submit():
            user = self.appbuilder.sm.auth_user_ldap(
                form.username.data, form.password.data
            )
            if not user:
                flash(as_unicode("Usuário não Encontrado ou Instabilidade no servidor LDAP"), "warning")
                return redirect(self.appbuilder.get_url_for_login)
            login_user(user, remember=False)
            return redirect(self.appbuilder.get_url_for_index)
        return self.render_template(
            self.login_template, title=self.title, form=form, appbuilder=self.appbuilder
        )

the credentials apparently received through LoginForm_db ():

class LoginForm_db(DynamicForm):
username = StringField(lazy_gettext("User Name"), validators=[DataRequired()])
password = PasswordField(lazy_gettext("Password"), validators=[DataRequired()])

which in turn receives the values ​​from the login screen that is written in flask in the following:

 <form class="form" action="" method="post" name="login">
    {{form.hidden_tag()}}
    <div class="help-block">{{_("Enter your login and password below")}}:</div>
    <div class="control-group{% if form.errors.openid is defined %} error{% endif %}">
        <label class="control-label" for="openid">{{_("Username")}}:</label>
        <div class="controls">
            <div class="input-group">
            <span class="input-group-addon"><i class="fa fa-user"></i></span>
            {{ form.username(size = 80, class = "form-control", autofocus = true) }}
            </div>
            {% for error in form.errors.get('openid', []) %}
                <span class="help-inline">[{{error}}]</span><br>
            {% endfor %}
    <label class="control-label" for="openid">{{_("Password")}}:</label>
            <div class="input-group">
            <span class="input-group-addon"><i class="fa fa-key"></i></span>
            {{ form.password(size = 80, class = "form-control") }}
            </div>
            {% for error in form.errors.get('openid', []) %}
                <span class="help-inline">[{{error}}]</span><br>
            {% endfor %}
        </div>
    </div>
<div class="control-group">
        <div class="controls">
    <br>
            <input class="btn btn-primary btn-block" type="submit" value="{{_('Logar')}}">
    </div>
</div>
</form>

I was thinking of doing something that can send the credentials authenticated in our proprietary system (developed in java) through the url and receive them in this form of the superset and consequently log in.

I'm almost sure it shouldn't be the safest method, but I'm a beginner in programming and can't think of anything better. Maybe the Token but I don't even know where to start.

User logged into another system, (where I can redeem the user and password), when redirected to the superset, must be automatically logged in. How to do this ?


Solution

  • You can create a RESTful API to handle user authentication as below

    from flask import request, make_response, jsonify, session
    from flask_appbuilder.api import BaseApi, expose, rison, safe
    from flask_appbuilder.security.decorators import protect
    
    from . import appbuilder
    from flask_login import current_user, login_user
    from app import db
    
    
    
    class LoginApi(BaseApi):
    
        resource_name = "login"
        
        @expose('/loginapi/', methods=['GET','POST'])
        #@has_access
        
        def loginapi(self):
            if request.method == 'POST':
                username = request.json['username']
                password = request.json['password']
    
                user = self.appbuilder.sm.auth_user_db(username, password)
                
                
                if str(user) != "None":
                   
                  login_user(user, remember=False)
                  if current_user.is_active:
                   username = current_user.username
                   status  = current_user.active
                   response = make_response(jsonify({'message': 'Login Success',
                                      'severity': 'info','Username': 
                                                               username,'Status':status}))
            return response
    

    For details on how to create a REST API refer to this this. https://flask-appbuilder.readthedocs.io/en/latest/rest_api.html