aspose file tools*
The moose likes JSF and the fly likes NonFacesRequestServlet another look Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » JSF
Bookmark "NonFacesRequestServlet another look" Watch "NonFacesRequestServlet another look" New topic
Author

NonFacesRequestServlet another look

ed connell
Greenhorn

Joined: Oct 26, 2009
Posts: 14
Disclaimer: JSF newbie.

Dev Env: Eclipse Galileo, JSF1.2, Tomcat6

Anticipating a situation where authentication is done external to the in development JSF application.

Successful authentication will invoke my application with a couple inputs describing the user, let's say /url?USERID=GREENHORN. Simple enough, right?

Now, I'm assuming the JSF app cannot be invoked directly and make use of USERID directly.

This I'm assuming is where the NonFacesRequestServlet mockup shown at http://wiki.apache.org/myfaces/InvokingJsfPagesWithStandardUrls comes into play.

I setup navigation rule from "/fake_out.jsp" on outcome success to "/moose.jsp" and have the mockup servlet successfully render the primary JSF page (moose.jsp). That page will have a backing bean (how to feed USERID into that I've not solved yet), and let's say 3 input fields. The form will have action and validation, the beginning of my JSF application.

Trouble - when the JSF moose.jsp page renders, the submit action feeds back to "moose.jsp" which throws a "requested resouce not available" error. If I run a modified "moose.jsp" outside of the servlet mockup, all actions feed to "moose.faces".

If I can't overcome this hurdle, I'll have to ditch JSF altogether. I though about trying to capture the rederred output and rewrite the "moose.jsp" to "moose.faces" but haven't been successful on that yet.

Any clues?

Thanks
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16145
    
  21

I didn't quite understand all that. But I've use the J2EE standard security system with JSF for years with no problems, getting my external authentication and authorization info from databases, Microsoft Active Directory, web services and xml files.


Customer surveys are for companies who didn't pay proper attention to begin with.
ed connell
Greenhorn

Joined: Oct 26, 2009
Posts: 14
I'm a little unclear on the exact details, but here's what I'm assuming.

The web/app server traps my JSF url. If the user is not auth'd it redirects to the auth page. The auth page is external to the JSF application. The auth page takes credentials, userid/password, validates then redirects to my application URL as a post with USERID as an input param.

Makes sense so far?

My application URL wants to be an entry to a JSF application. How do I pass that USERID into the JSF application and say use it in a backing bean on the first page?

Is this a stupid question?
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16145
    
  21

ed connell wrote:

Is this a stupid question?


No, but it's a dangerous one. If an application can transfer a userID to a webapp via a URL, so can a hacker. ANY userID. Including the administrator userID(s).

There's nothing inherently bad about using an external page for security, but that's not a safe way to do it.

Single Signon security systems are an example of a safer way. The SSO system typically jacks into the web application's internal security infrastructure and provides services behind the scenes. The data is passed internal to the server, so it's not at risk to external attack.
ed connell
Greenhorn

Joined: Oct 26, 2009
Posts: 14
Funny how you should mention that. This is an internal network, and the "single sign on" application is exactly the concept I'm referring to. I believe it runs as a plugin on the web/appserver completely unbeknownst to the JSF application. I'm not clear on the exact details of the interactions. If I assume the plugin runs as a wrapper on the same server, I think my issue is the same. It is not part of a JSF application. How does the resultant USERID from that signon get passed to my JSF application so the JSF app can use it as part of its processing?

Is that a stupid question?
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16145
    
  21

SSO can be a little tricky. It may be the only time that Microsoft actually made something secure by default, so participants had to set an Internet Explorer option to make it work properly. What it does is enable the exchange of security tokens between the various SSO participants, which is done without any actual code or configuration changes to Java webapps.

Container-managed security in J(2)EE is primarily done via declarations in web.xml, aided by whatever additional checks you might need to add into the executable code. The "wrapper" is the entire web application server. In the case of Tomcat, the actual security mechanism is implemented via plug-in components called Realms. Similar mechanisms apply to the other J2EE servers like WebSphere and WebLogic.

There are several SSO realm options available for Tomcat, although I think they're all 3d-party add-ons and not part of the actual Tomcat distro itself.
ed connell
Greenhorn

Joined: Oct 26, 2009
Posts: 14
Maybe we're getting somewhere now. But, I'm still at a loss on my issue.

Tomcat is just my dev environment. Actual target is IBM Websphere.

If the security mechanism is implemented as Realms for argument sake, and Realms were to gather the USERID field as part of the container managed auth, how would that USERID be made available to the JEE Webcontainer so it can be accessed by the initial JSF application page, assuming I got my lingo correct.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16145
    
  21

It's in the JavaDocs. What you actually get constructed when you're using Container-managed security is an object that implements the User Principal interface. So you can get the userID by simply calling the getRemoteUser method of the HttpServletRequest, which effectively calls getUserPrincipal().getname(). If the user is not logged in, the user ID will be null. You can also use the request.isUserInRole() method to test to see if the user is allowed to act in the indicated security role.



ed connell
Greenhorn

Joined: Oct 26, 2009
Posts: 14
Thanks for your time, and your replies, Tim.

I'm not exactly sure you've answered my question, but you have given me some things to think about and look at as my stuff evolves. I think my question was a little more general, and I didn't necessarily want to get into a discussion about an authorization system. So, I'll try to phrase it again, in my usual stupid fashion.

Try to imagine a JSF application which needs an externally supplied input "FOO" that is not hard coded in faces-config.xml as a managed-bean property. If the primary JSF page is moose.jsp, I cannot launch the application as moose.jsp?FOO=xyz or moose.jsp?FOO=abc, correct? The way I read my google hits, I thought that was one of the issues the "NonFacesRequestServlet" was offering to address?

If I want FOO to become a managed-bean property, and carry forward throughout the session, again, how can that be done?

Sorry for being so dense.
Tim Holloway
Saloon Keeper

Joined: Jun 25, 2001
Posts: 16145
    
  21

It's quite possible to use an HTTP GET request to read parameters from a JSF URL initial request. However, JSF differs from other frameworks in that the form (view) displayed is often carried over several request/response sessions. The process itself is called "postback", and, like its name implies, it's done via HTTP POST. So while you can capture parameters on the initial request, they then need to be safely stowed somewhere (in the bean itself is OK as long as it's a session-scope or higher bean).

JSF backing beans ideally are "pure" JavaBeans, and the less javax.faces items in them the better, so one way to avoid putting some fairly convoluted JSF-specific code into the bean is to use an assistive facility such as PrettyFaces. PrettyFaces allows you to define direct-access GET-form URLs in a config file, then it parses the GET requests and injects the values into the backing bean(s), saving the bean the need to reach out and grab the data. This type of mechanism is scheduled to be a standard part of JSF2.0.

Of course, as I mentioned, one thing you don't want to provide on a URL, regardless of which mechanism you use is a plain-text security ID. That's like putting a side-entry screen door in a submarine.
Samuel March
Ranch Hand

Joined: Oct 28, 2009
Posts: 39

faces servlet invokation by path /faces/*
faces servlet invokation by filename-extension-reference .faces

One of the above two is configured in web.xml for the faces servlet.

<jsp:forward page="faces/mypage.jsp">
<jsp:param value="<%= request.getPamater("username") %>" />
</jsp:forward>

or

<jsp:forward page="mypage.faces"><%-- filename is mypage.jsp --%>
<jsp:param value="<%= request.getPamater("username") %>" />
</jsp:forward>


More complexly, you can set up a JSP bean in the same folder as the managed beans.
Throwing values from one bean to another uses an intermediary bean with a scope of none.

You can use JSP in a JSF page.


...did you have the fish?!............................ No.
ed connell
Greenhorn

Joined: Oct 26, 2009
Posts: 14
Thanks to you both.
 
 
subject: NonFacesRequestServlet another look