2011-11-15 26 views
6

Ho una pagina di accesso in cui ho un bean utente per autenticare nome utente e password per una persona. Questo bean è Session Scoped. Se qualcuno scrive un URL e prova a saltare la pagina di accesso, come posso verificarlo e reindirizzarlo alla pagina di accesso?Verificare se esiste una sessione JSF

D'altra parte. Supponiamo che io abbia effettuato l'accesso e stavo lavorando e all'improvviso esco per un po 'e la mia sessione scade. Quando torno e tento di interagire con il modulo, invia un messaggio che mi avvisa della scadenza della sessione. Come posso ridirezionare nuovamente il modulo di accesso quando questo si verifica?

Grazie in anticipo. Spero di spiegarmi.

Mojarra 2.1.4, Tomcat 7, Tomahawk 1.1.11

risposta

14

Se qualcuno scrive un URL e cerca di saltare la pagina di login, come posso controllare che e lo reindirizza alla pagina di login?

Sembra che tu stia utilizzando l'autenticazione locale. In tal caso, è necessario implementare un servlet filter. JSF negozi con scope di sessione gestita fagioli come attributi di HttpSession, quindi si può solo controllare che nel doFilter() metodo:

HttpServletRequest req = (HttpServletRequest) request; 
UserManager userManager = (UserManager) req.getSession().getAttribute("userManager"); 

if (userManager != null && userManager.isLoggedIn()) { 
    chain.doFilter(request, response); 
} else { 
    HttpServletResponse res = (HttpServletResponse) response; 
    res.sendRedirect(req.getContextPath() + "/login.xhtml"); 
} 

Mappa filtro su un modello di URL che copre le pagine protette, per esempio /app/*.


Quando ritorno e cercare di interagire con il modulo invia un messaggio avermi avvertito la scadenza della sessione. Come posso reindirizzare nuovamente al modulo di accesso quando questo si verifica?

Comprendo che ciò riguarda le richieste Ajax? Per le normali richieste potresti aver usato un <error-page> in web.xml. Se l'impostazione lo stato metodo per cliente di risparmio in web.xml come segue

<context-param> 
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name> 
    <param-value>client</param-value> 
</context-param> 

non è un'opzione, allora avete bisogno di implementare una consuetudine ExceptionHandler:

public class ViewExpiredExceptionHandler extends ExceptionHandlerWrapper { 

    private ExceptionHandler wrapped; 

    public ViewExpiredExceptionHandler(ExceptionHandler wrapped) { 
     this.wrapped = wrapped; 
    } 

    @Override 
    public void handle() throws FacesException { 
     FacesContext facesContext = FacesContext.getCurrentInstance(); 

     for (Iterator<ExceptionQueuedEvent> iter = getUnhandledExceptionQueuedEvents().iterator(); iter.hasNext();) { 
      Throwable exception = iter.next().getContext().getException(); 

      if (exception instanceof ViewExpiredException) { 
       facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, "viewexpired"); 
       facesContext.renderResponse(); 
       iter.remove(); 
      } 
     } 

     getWrapped().handle(); 
    } 

    @Override 
    public ExceptionHandler getWrapped() { 
     return wrapped; 
    } 

} 

(si noti che questo particolare esempio naviga verso viewexpired , quindi prevede una pagina di errore

Quanto sopra deve essere cotto dal seguente ExceptionHandlerFactory implementat ione:

public class ViewExpiredExceptionHandlerFactory extends ExceptionHandlerFactory { 

    private ExceptionHandlerFactory parent; 

    public ViewExpiredExceptionHandlerFactory(ExceptionHandlerFactory parent) { 
     this.parent = parent; 
    } 

    @Override 
    public ExceptionHandler getExceptionHandler() { 
     return new ViewExpiredExceptionHandler(parent.getExceptionHandler()); 
    } 

} 

che a sua volta deve essere registrato in faces-config.xml come segue:

<factory> 
    <exception-handler-factory>com.example.ViewExpiredExceptionHandlerFactory</exception-handler-factory> 
</factory> 
+0

Ho avuto un piccolo dubbio in merito. Mi è stato chiesto di aggiungere un comando Link che dice "Vai alla pagina principale" ma quando faccio clic su di esso, va prima alla pagina ViewExpired e quindi devo fare di nuovo clic per andare alla pagina principale. Come posso andare direttamente alla pagina principale senza fare doppio clic sul comando link? – BRabbit27

+1

Rendilo normale '' che invia una nuova richiesta GET senza la necessità di visualizzare lo stato. Non è necessario inviare alcun dato tramite POST, giusto? – BalusC

+0

Questo ha risolto il problema, ma ne è apparso un altro. Se rimango nella pagina di accesso, si sta verificando anche ViewExpiredException. Come evitarlo? – BRabbit27

1

Se si implementa il proprio sistema è possibile aggiungere un attributo di utente chiamato sessione o qualsiasi altra cosa. Questo attributo può essere booleano, quindi ogni volta che si avvia la sessione è possibile impostare questo attributo su true.Scrivi un metodo chiamato permesso ad esempio:

public void permission() throws IOException { 

     if(userStatelessBean.getSession() == false) { 
      System.out.println("*** The user has no permission to visit this page. *** "); 
      ExternalContext context = FacesContext.getCurrentInstance().getExternalContext(); 
      context.redirect("login.xhtml"); 
     } else { 
      System.out.println("*** The session is still active. User is logged in. *** "); 
     } 
    } 

Su ciascuno di pagina JSF (per questo esempio) che si desidera avere restrizioni su, è possibile aggiungere il seguente codice, proprio all'inizio della vostra pagina:

<f:metadata> 
    <f:event type="preRenderView" listener="#{sesija.permission()}"/> 
</f:metadata> 

cosa questo sta per fare è chiamare il JSF ManagedBean con nome dell'oggetto sesija prima del rendering della pagina e controllare se i rulles che hai creato nel metodo specificato sono soddisfatti o meno.

spero hai trovato utile,

Grazie.

+0

U.V. in quanto mi ha aiutato a gestire i permessi ma questo non risponde alla vera domanda (gestione delle visualizzazioni scadute) –

Problemi correlati