• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

After logout in JSF relogin withtout credentials possible

 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

context:
- JSF on glassfish 3.1
- FORM based authentication (realm via a derby database)
- I am using no servlets but JSF
- "process":
(1) on requesting the base URL index.html is loaded which includes a link to /protected/welcome.xhtml
(2) click on that link => due to the login requirement (see web.xml below) login.html is loaded
(3) user fills in credentials and submits the form (to a UserBean)
(4) welcome.xhtml is loaded successfully upon successful login
(5) user logs out from welcome.xhtml via button and is redirected to index.html

Problem: The logout is not working correctly:
(a) When after the logout the login button is pressed again but without providing credentials then welcome.xhtml again is loaded (without any user information). That shouldn't be possible. It cannot be the cache (tested by deactivating the cache in the browser).
(b) It does not delete the session (session cookie not deleted on the client and keeps the same value).


web.xml

faces-config.xml


Regards,

Dom
 
Ranch Hand
Posts: 218
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Hi, I just checked my code and I see that I've commented out the call to session.invalidate() and
replaced it with this:



I really can't recollect why I did this and unfortunately at that time had not put into place a proper
changelog & version control so the reason is lost, but perhaps you could try this alternative approach.

Regards,
Brendan.
 
Saloon Keeper
Posts: 27762
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There's something wrong with this picture.

Container-managed security does not route the login process through application code. The login page is displayed by the server directly, and the server reads the returned login form and processes it. At no time is the application even aware that the login took place, and in particular, the FacesServlet is never invoked. That's why they call it container managed security.

So there's no way you could be populating JSF beans from data on the login page.
 
Brendan Healey
Ranch Hand
Posts: 218
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
>So there's no way you could be populating JSF beans from data on the login page.

Let's say you've built a mail application, you login with container security and don't populate
any backing beans with data from the login page, whose mail are you going to display? I'm
not sure I get your point, you've got to be able to know who has logged in surely.

Regards,
Brendan.
 
Tim Holloway
Saloon Keeper
Posts: 27762
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Container-managed security supports Single Signon. Or, in other words, if the proper Realm was configured on the server, a user who had logged into a completely different application written in a completely different language on a completely different server would never see your login screen, because SSO is "login once, run everywhere". For example, OpenID, where I can login to google and not have to login again to SmartSheets. JSF container-managed security supports SSO from the get-go; no application modifications or custom code required. In fact, even the config information in web.xml doesn't change.

But aside from that, it's a dicey security practice to attempt to do any sort of business logic in the middle of the login process anyway. It introduces the possibility that someone could exploit access to an object before security was fully established.

On the other hand, you CAN tell the userID quite easily, although not directly from JSF. When the container sets up a security context either when it logs you in or when it checks with SSO and obtains confirmation, a UserPrincipal object is constructed and used as an anchor for your application security. This object can be read from the HttpServletRequest object. You can also get the userId directly from the HttpServletRequest.getRemoteUser method. I normally create a special JSF Utilities class to hold methods that need to root around under the FacesContext in order to keep JSF-specific code out of my POJOs, and one of the methods I generally provde is a "getUserId" method.

Since the container maintains security, not the applications, there is, in fact, the only way a container-secured app can actually detect that a login ever happened. If the previous request had a null userPrincipal/remoteUser, and the current request has non-null values, someone, somewhere, somehow logged into the security system between the first request and the dispatching of the second request.
 
Brendan Healey
Ranch Hand
Posts: 218
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think we're singing off the same hymn sheet here. My welcome file is a secure page so
the user would need to be authenticated to access it. This has a preRenderView which
calls getRemoteUser() and display data for the relevant user. I hope this is ok because
I don't see any other way of doing it.

Back to the OP: was there a problem with my suggestion to call logout()? if so, what
are you supposed to do to logout. I'm pretty sure I researched this and this was the
recommended thing to do.
 
Tim Holloway
Saloon Keeper
Posts: 27762
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You should be OK on the PreRenderView. The security system kicks in when the protected URL is requested (PLEASE NOTE - URL, not RESOURCE!).

If the user fails login, the URL request is discarded and nothing ever reaches the app at all. However, if the user validates (logs in), then the URL will be processed without further interference, and the security context (UserPrincipal and remoteUserId) will have been initialized before the application code is called.

One thing I did notice was the comment about Portlets. Each Portlet is a specialized webapp and Portlets most definitely want SSO, because the alternative would be to force a login screen for every stinkin' portlet on the portal webpage. Likewise, the idea of logging out of a single portlet is meaningless. It's an all-or-nothing deal.
 
Dom McMillan
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That leaves me with the initial questions. In the meantime, I checked again my app with the following results:
1.) Start of the application (index.html with the link to a CMS-protected area)
Result: no cookie yet set, and hence no session established
2.) Klick on the link to the protected area. As a result not the welcome.xhtml is loaded but login.html (declarative security)
Result: a cookie is set, in the specific test with value 50033e41d18d500e302036f6eb74
3.) Enter credentials and submit form; welcome.xhtml of the protected area is loaded
Result: a new session is established (I assume that is the security session) with cookie value 500736ddf603308a1e58f032b08e
4.) Logout again. session.invalidate() is called. Again index.html is loaded.
Result: Still the same cookie is set on the client: 500736ddf603308a1e58f032b08e
5.) Click again on the link to the protected area
Result: welcome.xhtml is opened but without information from the backing bean and a new session is established with cookie value 502f6e71e4ca1580e9761cf8d983

So, questions:
- After step 4 I would have assumed the cookie to be deleted. A possible explanation for that behaviour could be that the server is deleting the session only on the server but not on the client. That means the cookie is still available on the client but without a corresponding session on the server. Is that understanding correct? If not, why is the session still existant, although session.invalidate was called?
- What can be done to avoid after step 5 the loading of welcome.xhtml? What would be a "good" way to solve that?
- Where can I find more info/readings/books about the mentioned security context (UserPrincipal and remoteUserId) - to get deeper into the subject?

Regards,

Dom

 
Tim Holloway
Saloon Keeper
Posts: 27762
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It took me a minute, but I think I can explain.

I never really paid attention to when/how security cookies are deleted. Deletion of the secured session on the server is what counts. After all, Bad People could simply replay a logged-out cookie otherwise!

The login page isn't really a part of the application process. If/when needed, the container will present it and process it, but it's all transparent to the webapp. All the webapp really knows is that when that protected URL is processed, security has been established.

As I mentioned earlier, container-managed security applies itself to URLs, and not to resources. This can be a problem in JSF, since the URL often lags the resource. It's what the "redirect" directive on your logout action is supposed to be addressing.

Keep a close eye on the URLs as you progress - especially the ones on forms and hyperlinks. They're what's probably causing the anomaly. Use the "View Page" source option on your browser if you need to check the generated URL.

As far as documentation on the User ID and UserPrincipal go, all I ever had was the J2EE JavaDocs. The user ID is simply the login ID. UserPrincipal is mostly stuff that apps can't use, except for the user ID property. Its main virtue is that it's present when you're secure and absent (null) otherwise.
 
Dom McMillan
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm not sure whether I do understand you correctly:
- with respect to the cookies you can't really say because you didn't focus on it in the past.
- with respect to the protected page being loaded you can recommend to check whether the links (URLs) are correct? (they are)
Is that what you mean? Because as of now I miss a hint on what the problem could be and how I could solve it. An "anomaly" is either a bug or a feature. If it is a feature then something is wrong in my app. If it's a bug then someone might already know about it - since my application is not very sophisticated.
 
Tim Holloway
Saloon Keeper
Posts: 27762
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, the cookies aren't important, because, as I said, the server is in charge of what it will do with a session ID.

The URLs to check are what's actually being submitted, not what's coded, since there can be a difference between the 2, especially when you present a page from JSF.
 
Dom McMillan
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@Brendan: thanks for your advice. Much appreciated!
@Tim: thanks for your rather general comments on JSF.

In "core JAVASERVER(TM) FACES, THIRD EDITION" from DAVID GEARY and CAY HORSTMANN on page 525 I found the following comment: "NOTE: Currently, there is no specification for logging off or for switching identities when using container-managed security. This is a problem, particularly for testing web applications. GlassFish and Tomcat use cookies to represent the current user. You need to quit and restart your browser (or at least clear personal data) whenever you want to switch your identity."

So currently it seems logging out is only possible with application managed security, i.e. it needs to be programmed within the application.

I'll set this thread to resolved.
 
Tim Holloway
Saloon Keeper
Posts: 27762
196
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am highly sceptical about that last assertion. None of the apps I write have run into that problem. The closest thing I know of is in when you use BASIC authentication rather than form-based authentication, where the only way to logout is to shutdown the browser.

I have switched identities by logging out via session.invalidate.
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I am using jsf 2.0 and I had a similar problem with the one described here (identical actually) and I solved it by using the following code for logout:


In my case "Admin.xhtml" is your index.html file. I suspect that response.sendRedirect() does the trick, but I do not know why. Maybe a more informed person can shed light on it.

The same code, with a different signature though (i.e. did not work.

Regards,

VRoy
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic