Tomasz Szawara
Tomasz Szawara

Reputation: 87

Logout user - Java EE 6 Security

I have one servlet representing secure content, annotated as follows:

@WebServlet(name = "GreetingServlet", urlPatterns = {"/greeting"})

@ServletSecurity(
        @HttpConstraint(
            rolesAllowed = {"TutorialUser"} ) )

and web.xml as below:

    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
  <display-name>hello2_basicauth</display-name>


  <!--other servlet names and mappings are defined via annotations-->


  <security-role>
    <role-name>TutorialUser</role-name>
  </security-role>

  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>file</realm-name>
  </login-config>
</web-app>

when I've entered the /greeting path for the first time, username/password prompt appeared ( earlier I have created users for Jboss using add_user.sh). After inputing right credentials I was able to see the secure content offered by the servlet.

The problem now is that whenever I access the /greeting path again, I'm no longer asked for the credentials.

I have implemented below logout servlet:

    @WebServlet(name = "Logout", urlPatterns = "/logout")
@ServletSecurity(
        @HttpConstraint(
                rolesAllowed = {"TutorialUser"}                 // 403 if user not present ...    // default add user to file realm and assign to TutorialUser group
        )
)
public class Logout extends HttpServlet {

    public static final Logger logger = Logger.getLogger(Logout.class.getCanonicalName());

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        logger.info("---- Principal = " + request.getUserPrincipal());
        request.logout();
        logger.info("---- Principal = " + request.getUserPrincipal());
    }
}

however it doesn't work ( I can still access resource at /greeting without logging in). Console logs this when accessing /logout:

 INFO  [servlets.Logout] (http--127.0.0.1-8080-4) ---- Principal = duke3                                                                                              
 INFO  [servlets.Logout] (http--127.0.0.1-8080-4) ---- Principal = null  

Upvotes: 0

Views: 2783

Answers (1)

Nikos Paraskevopoulos
Nikos Paraskevopoulos

Reputation: 40298

Yes, this is the way BASIC authentication works. Roughly the sequence is:

  • With BASIC authentication, the browser remembers the protected resources and the credentials and sends them back with every request to the protected resource.
  • The server creates the session and authorizes the user based onthe session cookie, despite the fact that the credentials get sent again (so the server does not have to look at the database every time, just once per session).
  • The logout servlet gets called and correctly destroys the session. But, with the next request to the protected resource, the browser sends the credentials and the server transparently logs the user back in! (You can verify that by checking that the session cookie has changed after the logout.)

What can be done?

  1. Embrace the way things work, i.e. adapt your logic to BASIC authentication.
  2. Use FORM authentication (prettier and works as you seem to expect).

Upvotes: 2

Related Questions