javing
javing

Reputation: 12423

How to implement a logout when using form based security

I use a JDBC form based security realm, and i want to implement a logout, but when i click on the link i see this exception:

java.lang.RuntimeException: java.security.AccessControlException: access denied (java.lang.reflect.ReflectPermission suppressAccessChecks) ... Caused by: java.security.AccessControlException: access denied (java.lang.reflect.ReflectPermission suppressAccessChecks)

This is the EJB i created to do the loggout:

@Stateless(name = "ejbs/SessionSupportEJBImpl")
@DeclareRoles({"administrators","users"})
public class SessionSupportEJBImpl implements SessionSupportEJB {

    @PermitAll
    public void releaseUserState() {
        HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
                .getExternalContext().getSession(false);
        if (session != null) {
            session.invalidate();
        }
    }
}

Here i call it from a backing bean:

@Named("logoutBB")
@RequestScoped
public class LogoutBean {

    @EJB
    private SessionSupportEJB sessionSupportEJB;

    public String logout() {
        sessionSupportEJB.releaseUserState();
        return "index.xhtml?faces-redirect=true";
    }
}

And here the markup that should trigger it:

<h:form>
        <h:commandLink value="LOGOUT" action="#{logoutBB.releaseUserState}"/>
    </h:form>

My doubts are:

Upvotes: 5

Views: 3721

Answers (1)

Ernesto Campohermoso
Ernesto Campohermoso

Reputation: 7371

In first place my recommendation is that you don't invoke FacesContext in EJB because the FacesContext is an element of the "View Layer". The purpose of EJB are represent the "Bussines Logic Layer" and a best practice is to have the bussines logic isolated from de View because you can access to the bussines logic from many types of views.

About how to close the session, I suggest do the following:

Create a servlet and implement the method doGet in order to close the session as follows:

@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
  public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
        HttpSession session= req.getSession();
        session.invalidate();
        RequestDispatcher rd = req.getRequestDispatcher("/login.xhtml"); //The url where go after logout
        rd.forward(req,res);
  }
}

So you can add the following link in you html / xhtml pages for logout:

<a href="/logout">Logout</a>

If you are using JSF, for get the context path of you app, you can use:

<a href="${request.contextPath}/logout">Logout</a>

DISCLAIMER: I'm assuming that you are using Java EE 6. Also I don't tested the code (but I know that it works) if you have some problems of compilation please let me know

Upvotes: 5

Related Questions