aspose file tools*
The moose likes JSF and the fly likes Starting with JSF 2.0 - Clearing login page Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » JSF
Bookmark "Starting with JSF 2.0 - Clearing login page" Watch "Starting with JSF 2.0 - Clearing login page" New topic
Author

Starting with JSF 2.0 - Clearing login page

Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 154
OK, I'm making some progress with JSF 2.0 and much appreciate the help so far.

I've started to put together the bare outlines of a new application, but I'm having trouble getting the login page to automatically clear after use, or when the page is reopened from a new browser window. Obviously I don't want the user name and password to be saved across a new session.

I'm sure this is a problem that has cropped up many times, and I have looked around for various solutions, but have so far found none that work without inserting a JavaScripot call into the HTML page. My understanding is that JSF generates JavaScript, so in many cases it is not necessary to specifically insert JavaScript.

Listing (1) is the HTML file as follows, where I'm using Ajax:



and listing (2) is the corresponding bean:



On clicking the button "Option 1", this fires an action that directs one to the Option 1 page, and is supposed to clear the name and password, although obviously I will need to store copies of them internally for later use. However, based on what I've found, simply just calling setName("") and setPassword("") do not work, as they appear when a new browser window is opened. As a test I'm printing out the password here.

I've found out that if you add the getters and setters for UIInput objects in listing (2) corresponding to the name and password strings, and insert in the <h:inputText> tag in listing (1) binding="#{login.nameText}" for the user name, and likewise for the password, this works for Internet Explorer after clicking the "Option 1" button, closing the browser windows and reopening a new window for the login page, but does not appear to work for Firefox, which retains the name and password.

In order to get round this problem, I had to insert the JavaScript call onload="login.reset();" into the <h:body> tag and id="login" into the <h:form> tag. This clears the form when the page loads.

Is there some way of making sure the form is completely cleared without having to add a JavaScript call? I would most appreciate some advice on this.

csharp
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16065
    
  21

Well, before analyzing your problem, I'll do the short version of my standard rant:

User-designed security systems ---- AREN'T

I mean this. I've worked with many J2EE systems in mission-critical spaces over the years, and not only were none of them even remotely secure, most of them could be circumvented in under 5 minutes by non-technical personnel. This includes most especially those designed by some in-house "genius" and then foisted on the other developers. There is a security framework that is part of the J2EE and JEE standards that was designed by full-time security professionals, integrates more cleanly into the applications, and has gone for well over a decade without a reported breach. 99 times out of 100, it should be handling application user authentication.

Every time I see a book teaching J2EE that uses a user-designed login logic as an example (which is almost all of them), I have to reach for the blood pressure pills.

OK. Rant over.

I think your problem is that you're doing an AJAX request and the default scope of transmitted data and returned partial page update are too small. You need to add ajax tag options to widen the affected areas.

Incidentally, I always counsel people to minimize the use of raw HTML tags in JSF View definitions. There are a number of reasons why, but in the case of a basic login form layout like yours, one of the best ones is that it's less coding to do a h:panelGrid than a raw HTML table with all those row and column tags.


Customer surveys are for companies who didn't pay proper attention to begin with.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 154
Hello,

Could you ver kindly tell me how I can invoke the security framework so that it can be incorporated in my application. The code is very much in its early stages of development, so it will be some time before it goes live on a server.

I put the default <f:ajax> tag before the <h:inputText> and <h:inputSecret> tags, and the closing tag after the <h: outputText> tag, and left <f:ajax execute="name password" render="out"/> between the outer Ajax tags, but that still did not work.

Thanks for reminding me about the <h:panelGrid> tag. The original code had a lot of raw HTML, some of which I had to use as it was written for JSF 1.2, but <h:panelGrid> is in JSF 1.2. However, according to the documentation, it renders to HTML 4, and I want to be HTML 5 compliant as much as possible.

As an aside, the ":" in <hutputText> is rendered as a red emoticom, whereas by adding a space, as in <h: outputText>, it comes out correctly - funny.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16065
    
  21

The JEE security framework comes in 2 parts. The part that's in the webapp and the part that's in the webapp server (Tomcat, JBoss, WebLogic, whatever). The server part is known as the Realm and for details on configuring a Realm, check with the JavaRanch forum that specializes in your appserver.

The webapp part is configured in the webapp's web.xml file. You define a login and loginfail form page (these have to be straight HTML or JSP, not JSF, since the server executes them, not your app). You define security roles and assign one or more roles to secured URL patterns. You can also write code that obtains the userID using the HttpServletRequest getRemoteUser or getUserPrincipal() methods and you can also put logic in your action methods that test the user's authorization using the HttpServletRequest isUserInRole() method - I normally put the actual test logic in a separate utility class in order to keep things cleaner.

Primarily security is done by blocking unauthorized access to secured URL patterns by the server. Unauthorized users never gain access to secured application logic because the server blocks them before the application is even invoked. Security logic may or may not be used within the app for things like determining whether a user can only view or can view and change. Login is handled automatically without user logic.

One thing to note in JSF is that since URLs don't precisely track their resources in the normal course of events, you have to add redirect options to navigations to secured areas, since it's the URL that's secured, not the underlying resources (xhtml).

Other than the JSF part, most of the web.xml stuff is usually covered in basic J2EE books in the chapters on how to set up secure transport (https).
Mark Reyes
Ranch Hand

Joined: Jul 09, 2007
Posts: 426
Not exactly related to your question but this http://jugojava.blogspot.com/2011/02/jdbc-security-realm-with-glassfish-and.html could help your cause.

It uses Glassfish though so check your own app server.

This is how you authenticate using the application server and this is one of the sample 'realm' Tim is talking about.

For a more basic approach, read thru about JEE security first.

Just my 2 cents.


Sean Clark ---> I love this place!!!
Me ------> I definitely love this place!!!
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 154
Well, these two replies look like being very helpful indeed. In fact I'm using Glassfish with Eclipse, so the link should be particularly useful.

I'm still in the early stages of developing the application, and will look into the issue of security after I have something reasonable up and running to show the people I am working with here in France, who know little if anything about Java and probably nothing about JSF, so I'm on my own here.

In the mean time if some simple way of clearing a form with Ajax without having to specifically use JavaScript, this would be most appreciated.

I think the advice is definitely worth more than 2 cents, in Euros or US Dollars!
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16065
    
  21

The way to clear a form with AJAX is to have the AJAX listener code clear (or reset) the form's backing bean properties and code the f:ajax tag with a "render" option that re-renders the cleared controls.

This is distinct from a login page presented by the J2EE Container security system, however. For that environment, either the user logs in and the login page goes away entirely or the login fails and the loginfail page is displayed with cleared fields.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 154
OK, many thanks for your comments - I have not yet considered how to ensure the form is cleared when it is loaded, which will be the next bit of work to do, but right now I'm having a problem getting <h:selectBooleanCheckbox> to work properly.

The login form so far has has 5 rows, Name, Affiliation, E-Mail address, Password and Confirm Password, and I want it so that when the checkbox is checked, you only have to fill in the fields for the E-mail address and the password, otherwise all 5 fields have to be filled in.

Listing (1) is the HTML code for this, where depending on login.regFlag, the 3 input fields in the form can be disabled, and to show that they are, the background is styled gray. However, I'm unable to get the form changed when the checkbox is checked.

In fact an earlier version of this is online at http://phoenix.ens-lyon.fr/simulator , which you get to by clicking on one of the large gray buttons. That version made extensive use of JavaScript with JSF 1.2, but I want to avoid using JavaScript.

Some of the backing beans are here in listing (2):

Although public void updateCheck(AjaxBehaviorEvent event) is fired when I click the checkbox, this is not reflected in the form, so some advice on this would be very helpful. The idea is that the boolean regFlag is changed from true to fale, or the reverse.

Some of the getters, setters and actions associated with logging in are shown, but for brevity I've left out the rest of the code, which works.

Incidentally, the method public String getCheck() checks if the person is logged in, and has nothing to do directly with the status of the checkbox. This is a bad name that I must fix to avoid confusion.

Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16065
    
  21

None of the above will help you if you use J2EE container security. For one thing, the container handles login from start to finish entirely by itself without any user-written code at all, and that includes what's in JSF backing beans.

Secondly, the container login process is not a "normal" request. When an unauthenticated user requests a secured URL, the request is placed on hold, the container fetches the login page (designated in web.xml) and the container processes the userid and password that comes back from the client (after which, it pulls the original request off hold and continues). The container does not route the incoming user data through the normal web request processor and therefore it cannot invoke specialized control servlets such as the FacesServlet or the Struts ActionServlet. Without the FacesServlet, JSF view processing will not be done properly.

Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 154
OK, many thanks fot the advice, and suitable security will have to be included.

However, I will have several forms in this application which will not involve logging in, so security should not be an issue for them, but they will include check boxes, radio buttons, etc. Consequently I still need to know how to use Ajax to change dynamically the appearance and enable/disable status of parts of a form.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16065
    
  21

That will take us back to my original answer.

1. Code the f:ajax tag to indicate what input controls on the form containing the ajax tag will be submitted (default is to submit only the attached control).

2. Code your ajaxlistener method in the backing bean to initialize the values you want cleared.

3. Make sure that your f:ajax tag includes render values that list the controls whose values you want updated from the (re)initialized backing bean.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 154
OK, thanks, I put in three names in the render attribute of the first <f:ajax> tag in the form below, i.e "name", "affil" and "confirm". The first id with "name" does now change when I click the checkbox, but the others do not. If I reload the whole form, then all three are changed correctly, so for some reason Ajax is only changing the first, with the second and third unchanged.

The rest of the form is unchanged, except that with the second Ajax tag I check "email" rather than "name" as well as "password".

For now no changes relevant to this have been made in the bean, with the relevant methods below:

And yes, I know this is not relevant to a login form for reasons you mentioned earlier, and I've just checked out some links on J2EE container security. It's just that this is the only form I have up and running at the moment, but will transfer these ideas to the other forms when I have created them and deal with the issue of security in due course.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16065
    
  21

I can't see the reason why the other 2 render items aren't re-rendering without actually touching the project, but you're better off coding 'render="login"' there. Also, I have doubts about using the "prependId" attribute on the form.

Some EL suggestions:

1. You can use the word "not" instead of "!" for negation in EL. I prefer it, because the meaning is more obvious and it's visually more apparent.

2. I usually push complex EL such as your styleClass expressions into the backing bean. They keep the page simpler and it's murder to debug EL compared to debugging Java code.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 154
Well, just this moment I discovered that it works correctly with Firefox, but not IE (version 9), so something is browser dependent. I will try 'render="login"'.

I looked at how to get a style from a backing bean, but you can't simply do something similar as to getting values that are rendered. If you have some advice on that, it would be appreciated. I want to avoid many lines of complicated bolierplate code if possible.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16065
    
  21

There is a problem with IE9 and RichFaces 3, if you're using it. A variant of this problem may exist even if you are not.

The RichFaces people decided to forgo the common enterprise practice of continuing support for older releases of software once a new major release came out. Once RichFaces 4 went live, RichFaces 3 died completely and totally. They have formally declared that no further maintenance, bugfixes, etc. will be done.

The problem is that Microsoft - being Microsoft - introduced an AJAX library in IE9 without checking to see what existing - and conflicting components might already be popular and caused a major breakage in AJAX support for RichFaces 3.

You can forget about Microsoft saying "oops, we'll fix that", of course. Red Hat's JBoss RichFaces team isn't going to step in, so those of us with a heavy investment in RichFaces 3 are in a very unpleasant situation, since migrating from RichFaces 3 to RichFaces 4 is not just a matter of changing a Maven dependency version - it's closer to a migration from Microsoft Visual Basic to VB .Net. A lot of people are unhappy, and if they're like me, considering alternative JSF extension packages.

So the short of it is that it's possible that IE9 is aborting the your operation due to software conflicts.


Moving on:



Can be transformed to:


Plus:


BTW, the "Red Smiley" thing. I forgot to mention. You can click the "disable smilies" checkbox on the message editor to avoid it. Or use Code tags.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 154
OK, that works!!! Many thanks. In fact I had the logic the wrong way round on the web page anyway. I also mistakenly inverted regFlag in the method public void updateCheck(AjaxBehaviorEvent event), which now has nothing in it, as I had forgotten that of course the status of regFlag is read from the page. That method is required by Ajax, even though it is empty.

I don't know whether it's worth spending the time getting round the bug with IE9. I am not using RichFaces, but I'm thinking of using PrimeFaces once I get on a bit further with this project. I looked at RichFaces and Primefaces when I was working in the USA in 2010. At that stage the people I was working with decided to use PrimeFaces, which at that time was relatively new and used less than Richfaces. I checked up in the last couple of days, and noticed that Primefaces is used much more now. Any comments on that?
Mark Reyes
Ranch Hand

Joined: Jul 09, 2007
Posts: 426


I used Oracle ADF Faces since the company that I am working on is using it way before I came in. ADF Faces is Oracle's version of the JSF with many built-in capabilities.
Of course you are tied to the Oracle framework.

On the other side, while maintaining a community project. PrimeFaces really rocks! The support and the UI is really awesome. Getting started is really easy.

P.S.

Just my 2 cents again..
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16065
    
  21

I last looked at PrimeFaces when it was still a commercial-only project. However, it is a popular platform in the town where I live and it's also fairly popular here in the JSF forum.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 154
Many thanks for the information on PrimeFaces, which may be useful when I get further along in this project.

I've got most of this form sorted out, but there are still some issues, and yes, these ideas will be transferred to code where security is not an issue and the aspects of security will be dealt with further down the road after I've got the logic sorted out.

As given below, I've modified the form so that error messages are printed on the right if an incorrect password is given or any fields are empty. However, if all fields are empty, such as when the page is first loaded or the user clicks the "Reset" button, then obviously no error messages should be printed.

The message at the buttom of the form rendered by <h:outputText id="out" value="#{login.verify}"/> that is returned by "getVerify()" in the listing of the Java code is one of the four following:
1) Nothing - As is the case when the page is first loaded or the user clicks the "Reset" button.
2) A message indicating that the user has not logged on when he clicks the "Login" button when all fields are empty.
3) A mesage indicating failure if he does not fill in the form properly, either has left some fields blank or has provided an incorrect password.
4) A message indicating success if he has filled in the form correctly.

Only in the last case is the loggedIn flag set to true,

I want the form so that if all fields are empty, nothing is displayed on the right, but if some of the fields are filled in incorrectly or not at all, messages on the right are displayed indicating that the password is bad or a field is blank.

As the methods "getVerify()" and "restLogin()" are both invoked when the page is loaded or the reset button is clicked, I have to differentiate between this and when the "Login" button is clicked, as in that case only "getVerify()" is invoked, and the flag "resetForm" is used to differentiate between these cases.

All this appears to work fine, however, I'm having trouble getting text displayed on the right of the form. If I fill in the form incorrectly and click "Login", the required message is displayed below it and the appropriate values of "nameMes", "passwordMes", etc. are updated, but are not dispoplayed on the right. I have to click "Login" a second time before these are displayed. For some reason the string returned by "getVerify()" is displayed correctly, but the updated values of "nameMes" etc. are not placed on the form by the relevant getters until "Login" is clicked" a second time.

The form in the web page is here:

and the relevant parts of the Java code are here:

Does anybody have any ideas why the string contained in "message" returned by "getVerify()" is rendered, but the strings in "nameMes" etc. are not rendered until "Login" is clicked a second time?

I would most appreciate some advice on this as I have spent quite a long time on the problem and the solution is not obvious to me, although it may be obvious to someone else.

Many thanks for any infomation.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16065
    
  21

I'm afraid this is a classic case of "TL;DR".

Before attempting to solve your example, which is long enough to make my eyes glaze over, I have to ask if you've considered letting JSF to do the work for you.

If you add the "required="true"" attributes to your input fields, JSF will automatically post a message to whatever "h:message for=" element has the same ID as the input field. No Java code required. You can also define a custom message, since the default one isn't very pretty.

While I understand that you're using login only for illustrative purposes here, I should mention that the J2EE standard login screen doesn't have to check for a logged-in user. That screen is never presented by the application program, only by the server itself (attempting to display it manually won't work). And the server presents the screen if and only if the user has made a request to a protected URL and isn't already logged in.
Christopher Sharp
Ranch Hand

Joined: Dec 12, 2007
Posts: 154
OK, many thanks, and I tried out the "<h:message>" tag and it works. I will now move forward to other parts of the code and leave the issues on login for the moment, but your advice will be made use of when I am working on other forms where security will not be an issue.

By the way, what does "TL;DR"? mean.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16065
    
  21

I think the single biggest problem have with JSF is getting their heads wrapped around the idea that JSF is all set up and willing to do common tasks with little or no code required and minimal reliance on JSF-specific classes. They make hard solutions out of easy ones.

TL;DR is a bit of Internet snark. Stands for "Too Long; Didn't Read". Most commonly applied in response to people who write long ranting manifestos in online forums, but this is the 21st Century, where we all have Attention Deficit Hyperactivity Disorder and anything that isn't bumper-sticker short gets pushed aside. Or, more realistically, if it can't fit easily on the screen, it doesn't get read properly. Reading an LCD can be hard on the eyes, anyway, which is why we encourage excerpting the trouble spots over complete listings.

At least you're lucky I have an older 1600-pixel high screen. The newer products all think people are only interested in videos and has at least 400 fewer vertical pixels to get the point across in.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Starting with JSF 2.0 - Clearing login page