简体   繁体   中英

Redirect after Login doesn't work (jsf-glassfish)

I am in a glassfish-jee/jsf-jpa scenario, when i try to access to a protected function in one of my ManagerBean (for which i don't meet the requirements specified by @RolesAllowed ) i get prompted with the login page as configured in the web.xml. after login i get redirected to the generic homepage (home.xhtml).

as my function returns void (it performs some business in the database) i would expect to get redirected to the same page i was after logging in.

the redirect thing works perfect when i try to access protected pages, but with protected functions which does not return anything it seems that "i come from nowhere and i'm going to nowhere" (originalURL is null, see the code below for details)

i have searched the whole day on StackOverflow , i have read lots of answers but none of them worked, so far these are my lines of code..

login.xhtml

   <h:form>
        <h:outputLabel for="username" value="Username" />
        <h:inputText id="username" value="#{LoginManagedBean.username}"
            required="true" />
        <h:message for="username" />
        <br />
        <h:outputLabel for="password" value="Password" />
        <h:inputSecret id="password" value="#{LoginManagedBean.password}"
            required="true" />
        <h:message for="password" />
        <br />
        <h:commandButton value="Login" action="#{LoginManagedBean.login}" />
        <h:messages globalOnly="true" />

    </h:form>

LoginManagedBean.java

   package userInterfaces;


 //imports

/**
 * Session Bean implementation class LoginManagedBean
 */
@ManagedBean(name="LoginManagedBean")
@ViewScoped

public class LoginManagedBean {
    //getters and setters

    private String username;


    private String password;
    private String originalURL;

    public LoginManagedBean() {
        // TODO Auto-generated constructor stub
    }

    @PostConstruct
    public void init() {
        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
        originalURL = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);
        String uri = ((HttpServletRequest) externalContext.getRequest()).getRequestURI();

        if (originalURL == null) {
            originalURL = externalContext.getRequestContextPath() + "/home.xhtml";
        } else {
            String originalQuery = (String) externalContext.getRequestMap().get(RequestDispatcher.FORWARD_QUERY_STRING);

            if (originalQuery != null) {
                originalURL += "?" + originalQuery;
            }
        }
    }

    public void login() throws IOException {
        FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext externalContext = context.getExternalContext();
        HttpServletRequest request = (HttpServletRequest) externalContext.getRequest();

        try {
            request.login(username, password); 
            externalContext.redirect(originalURL);
        } catch (ServletException e) {
          context.addMessage(null, new FacesMessage("Unknown login"));
        }
    }
       public void logout() throws IOException {
            ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
            externalContext.invalidateSession();
            externalContext.redirect(externalContext.getRequestContextPath() + "/login.xhtml");
        }

}

web.xml

    <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>TravelDreamDynamicWeb</display-name>
  <welcome-file-list>
    <welcome-file>home.jsf</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
    <url-pattern>*.xhtml</url-pattern>
    <url-pattern>*.jsf</url-pattern>
  </servlet-mapping>
  <login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
      <form-login-page>/login.xhtml</form-login-page>
      <form-error-page>/loginError.xhtml</form-error-page>
    </form-login-config>
  </login-config>
  <error-page>
    <error-code>403</error-code>
    <location>/loginError.xhtml</location>
  </error-page>
  <error-page>
    <error-code>500</error-code>
    <location>/login.xhtml</location>
  </error-page>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Pagine Cliente</web-resource-name>
      <description></description>
      <url-pattern>/cliente/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>CLIENTE</role-name>
    </auth-constraint>
  </security-constraint>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Pagine Impiegato</web-resource-name>
      <description></description>
      <url-pattern>/impiegato/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>IMPIEGATO</role-name>
    </auth-constraint>
  </security-constraint>
</web-app>

the specific function's implementation (just for knowledge, i'm sorry it's a mixture of italian and english

@Override
@RolesAllowed({"CLIENTE"})
public void aggiungiACarrelloMgr(int idPacchetto) {
    String username=FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
    Query query=em.createQuery("SELECT u FROM UtenteRegistrato u WHERE u.username='"+username+"'");
    List<UtenteRegistrato> utente= query.getResultList();
    int idCarrello=utente.get(0).getIdCarrello();
    Carrello carrello=new Carrello(new CarrelloPK(idCarrello,idPacchetto));
    em.persist(carrello);
}

the command button in "VisualizzaPacchetti.xhtml" (visible to not logged users) which tries to invoke the protected function (which triggers the forward to login page after launching a javax.ejb.AccessLocalException )

<h:commandButton action="#{PacchettoManagedBean.aggiungiACarrello(PacchettoManagedBean.pacchetti.get(statoPack.index).idPacchetto)}" value="+CARRELLO" />

Thank Your for Your Time, please tell me if i missed something in my explanation, and sorry for my bad english

Massimo

Hi Massimo and welcome on Stack Overflow. I quickly checked your code and it seems your LoginManagedBean is ViewScoped, which means that it keeps it state until the view is the same. In your case you are requesting login.xhtml which is probably different from your original view, and for this reason the state of LoginManagedBean is lost.

Try changing @ViewScoped with @SessionScoped in LoginManagedBean .

I don't know if it fits your logic, in case it doesn't just create a session scoped bean for login related stuff since you would need it anyway. Looking at your method names I assume you're building an ecommerce (i'm italian as well) so you may have a session scoped bean already around.

To solve my problem i used a custom version of the login described in this page http://mrj4mes.blogspot.it/2013/04/how-to-redirect-to-original-page-after.html

Pay attention, i had to change the suggested

<f:view>
<ui:param name="originalURL" value="#{request.requestURI}?#{request.queryString}" />
<f:metadata>
<f:event rendered="#{not userSession.loggedIn}" type="preRenderView" listener="#{userSession.recordOriginalURL(originalURL)}" />
</f:metadata>
</f:view>

to this

<f:view>
<f:metadata>
<ui:param name="originalURL" value="#{request.requestURI}?#{request.queryString}" />
<f:event rendered="#{not userSession.loggedIn}" type="preRenderView" listener="#{userSession.recordOriginalURL(originalURL)}" />
</f:metadata>
</f:view> 

hope this helps someone with the same problem. Good Luck

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM