2012-08-04 1 views
9

Autenticazione e autorizzazione possono essere integrati nel Flask tramite il Flask Login e Flask-Principal plugin. (O anche potenzialmente tramite il plugin Flask-Security.)Flask-Admin + (Flask-Login e/o Flask-Principal)

TUTTAVIA: Flask-Admin plug --another che fornisce un cruscotto backend - non è un progetto registrato ... e, io credo (tanto che ho può dire), i decoratori usati da Flask-Login e Flask-Principal - e che sono altrimenti richiesti per un utente per accedere a una vista renderizzata ... questi decoratori operano solo su viste che fanno parte di un progetto registrato.

due domande:

1) Come posso registrare Flask-Admin come un progetto nella mia app, e/o altrimenti abilitare Flask-Login e/o decoratori Flask-Principali per proteggere viste associate Flask-Admin ?

2) Perché Flask-Login e Flask-Principal funzionano solo su oggetti che sono parte "nativamente" della mia app ... e non oggetti (ad es. Oggetti "Admin") che vengono importati da un plugin? Come posso aggirare questo problema ... se davvero lo percepisco correttamente?

Ritengo che questo sia il problema in quanto non mi preoccupo di creare viste protette per la pagina indice principale della mia app ... o qualsiasi altra pagina con una vista all'interno di un progetto. Non riesco proprio a farlo per la pagina indice Flask-Admin (che, di nuovo, non ha progetto).

risposta

11

Flask-Admin fornisce un altro modo di fornire l'autenticazione - è sufficiente sottoclasse il AdminIndex e BaseIndex vista (o osservazioni di contrib se è necessario solo quelli) e implementare il metodo is_accessible. Vedi the documentation per maggiori dettagli. C'è anche an example fornito nel repository.

+0

Grazie, Sean ... per me imboccando la documentazione per questo. Li ho rivisti e ho tentato di implementarli ... anche se senza risultato. L'uso del metodo is_accessible rende quindi non necessario utilizzare Flask-Login per proteggere il dashboard dell'amministratore? Significato: quindi non ho bisogno di un decoratore di Flask-Login per la def di qualsiasi visualizzazione di Flask-Admin? Devo dire, al di fuori del repository, i documenti sono sottili per l'autenticazione con Flask-Admin. Se, per caso, oltre il precedente repo, vi imbattete in un'altra implementazione pubblica di questa soluzione ... mi piacerebbe saperlo. – Sean

+1

@Sean: non è necessario il decoratore * Flask-Login *, ma è necessario utilizzare i metodi Flask-Login per autenticare l'utente. Se guardi [riga 85] (https://github.com/mrjoes/flask-admin/blob/master/examples/auth/auth.py#L85) e oltre l'esempio vedrai che le visualizzazioni di amministrazione sono accessibili solo se l'utente corrente è autenticato. Se un utente non autenticato tenta di accedere alle visualizzazioni amministratore, deve essere reindirizzato alla schermata di accesso. –

+0

Il collegamento a un esempio era esattamente ciò di cui avevo bisogno, grazie. – iurii

4

esempio semplice come utilizzare Flask-Admin con Flask-Principal

from functools import partial 
from flask.ext.admin import Admin as BaseAdmin, AdminIndexView 
from flask.ext.principal import Permission, identity_loaded, Need 
from flask.ext.security import current_user 

PartnerAccessNeed = partial(Need, 'access') 

class PartnerAccessPermission(Permission): 
    def __init__(self, partner_id): 
     need = PartnerAccessNeed(partner_id) 
     super(PartnerAccessPermission, self).__init__(need) 


@identity_loaded.connect 
def on_post_identity_loaded(sender, identity): 
    if hasattr(current_user, 'partner'): 
     identity.provides.add(PartnerAccessNeed(current_user.partner.id)) 

class PartnerAdminIndexView(AdminIndexView): 

    def __init__(self, partner_id, *args, **kwargs): 
     self.partner_id = partner_id 
     super(PartnerAdminIndexView, self).__init__(*args, **kwargs) 

    def is_accessible(self): 

     if current_user.is_anonymous(): 
      return redirect(url_for_security('login')) 

     if not current_user.is_partner(): 
      return False 

     permission = PartnerAccessPermission(self.partner_id) 

     if permission.can():  
      return True 

     return False 

class PartnerAdmin(BaseAdmin): 
    def __init__(self, partner_id, endpoint, name, subdomain, *args, **kwargs): 

     index = PartnerAdminIndexView(name=name, 
             endpoint=endpoint, 
             url='/dashboard', 
             partner_id=partner_id) 

     super(PartnerAdmin, self).__init__(base_template='mcnm/master.html', index_view=index, subdomain=subdomain) 
+1

Il ritorno di un reindirizzamento in 'is_accessible' viene valutato come True. Questo non è assolutamente quello che vuoi! – Javier