Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • How can make the logout feature work ?

  • Is is it mandatory to use the ejbs security annotations always on my EJBs to permit access?(When using a security realm)

  • Should i do this with a servlet instead of an EJB?

  • Is this approach wrong, should i try something else for the logout?

like image 452
javing Avatar asked Nov 24 '11 12:11

javing


1 Answers

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

like image 50
Ernesto Campohermoso Avatar answered Oct 12 '22 00:10

Ernesto Campohermoso