shale-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Mike Meessen (JIRA)" <j...@apache.org>
Subject [jira] Commented: (SHALE-287) Faulty behavior of the "token" component with Apache MyFaces >1.1.1
Date Wed, 08 Nov 2006 16:10:57 GMT
    [ http://issues.apache.org/struts/browse/SHALE-287?page=comments#action_38618 ] 
            
Mike Meessen commented on SHALE-287:
------------------------------------

Hi Craig,

I just spent a day of work trying to understand, reproduce and find a patch for the described
issue. 

At first a "management summary", details follow.

If the user supplied an invalid token as consequence of for example using the back button,
we have to remove the token attribute to avoid being stuck with the old (invalid) token forever.

Details:

* The fact that myfaces prior to v1.1.2 behaves differently then v1.1.2 and above seems to
be a very little bug in the old myfaces implementation concerning UIInput validation. As a
conclusion, I focused on shale and the token tag, trying to achive the behavior I experienced
with myfaces 1.1.1.

* In my opinion, two phenomenes appear at the same time here:
1) In certain cases, the token value should be regenerated to avoid the application to get
stuck.
2) In cases where the token detects that the submission it gets has not been initiated from
the last served viewId (thus, the user clicked the back button once or more), we'd need a
mechanism to redirect to the last served viewId, providing a fresh representation of that
viewId.

At first, I tried to fix point 1.

The token tag operates as standard UIComponent with standard jsf component validation to "manipulate"
faces behavior. If a valid token gets submitted, the application phases go through as normal:

* restoreView
* applyRequestValues
* processValidations    <= That's where the token tests it's validity
* updateModelValues
* invokeApplication
==> renderResponse

But, what if the submitted token value is invalid? It would look like this:

* restoreView
* applyRequestValues
* processValidations    <= That's where the token tests it's validity
==> renderResponse

Taking things a bit further, I noticed that since the "Apply Request Values" phase already
wrote the new (invalid) token value to the token UIComponent, this (invalid) value will be
used for rendering the response... So as a conclusion, the response will be generated with
the submitted (invalid) token value.

To avoid this, I simply reset the token value (I removed the TOKEN_ATTRIBUTE_KEY from the
UIComponent's attributes map) if the validation fails. Then, in the render response phase,
the token tests it's value and generates a new one.

The result is that I:
* successfully told JSF that a validation error occured, so I bypassed any model updates and
application invokes (the primary goal of the token component)
* delivered a fresh page to the user, displaying the latest valid state of the viewId
* generated a new token, so the user will be able to go on from the served page.

The only inconvenience I see applying this method is the following:
-------------------------------------------------------------------------------------------
When a token is generated, it is put in a map in session scope called "ShaleConstants.TOKENS".
When a valid token is submitted, the TokenProcessor.verify() method removes it from that map.
This is the right mechanism, since this token has now been consumed and should never be consumed
again.
BUT: in my case, where a token is re-generated due to an invalid request, the old token (which
would have been submitted by a valid request) will stay in the "ShaleConstants.TOKENS" map
in the session scope. With the current architecture, I think I have no chance to know what
would have been the correct token in order to remove it from that map.
I have been unable to find a *simple* way around that without having to change this mechanism...

I included a patchfile for shale(-core) which applies my one-line patch...
------------

As I mentioned before, this only solves the first phenomene...

To solve the second one (which would be "serve the right viewId even if an old page gets submitted"),
I think the only simple way would be:
* shale must keep in mind which was the last served viewId (page)
* whenever a HTTP POST request comes from another viewId as the one the user was supposed
to have in front of him, the last served viewId is re-served (with a re-generated token value).
That would be achieved by a redirect in the validation phase of the token... I know this is
not really pretty but I think it would solve any double-submit, back-button, etc. problems
we all are struggling with.

-----------

I hope this has been well described, it really isn't easy ;-)

Looking forward to hearing from you!!

Regards,
Mike Meessen

> Faulty behavior of the "token" component with Apache MyFaces >1.1.1
> -------------------------------------------------------------------
>
>                 Key: SHALE-287
>                 URL: http://issues.apache.org/struts/browse/SHALE-287
>             Project: Shale
>          Issue Type: Bug
>          Components: Core
>         Environment: OS: Microsoft Windows XP SP2
> Servlet Container: jakarta-tomcat-5.5.9
>            Reporter: Mike Meessen
>         Assigned To: Craig McClanahan
>         Attachments: shale-test-core.war, ShaleIssueDemo.war, ShaleIssueDemo.zip, Token.java.diff
>
>
> This issue appears when using Apache MyFaces as of version 1.1.2. The MyFaces project
states the following about their 1.1.2 release:
> [Quote]
> This is the first official release of what we are now calling the "core." The core refers
to the JSF 1.1 implementation as specified by JSR-127. It has passed Sun's TCK and is considered
to be 100% compliant with the spec.
> [/Quote]
> So as a conclusion, I think everyone who's still using MyFaces 1.1.1 should hurry upgrading
his code to be 1.1.2 compliant.
> Allthough Shale should be JSF-implementation-independant, it seems this issue appears
or not depending on the used MyFaces version.
> Steps to reproduce the issue:
> * Use a simple JSF submission form to which you add Shale's Token tag to check for illegal
form resubmissions.
> * As long as you submit the form correctly, everyting works fine.
> * Press F5 (page refresh) once, the browser warns about HTTP POST data resubmission.
> * Discard the warning and go on resending the same HTTP request.
> * Shale recognizes the resubmission and acts correctly (no application logic gets invoked).
> **** This is the part where the behavior changes according to what MyFaces version is
used:
> With MyFaces 1.1.1
> --------------------------
> * Resubmit the form correctly (using the submit button).
> ==> The workflow goes on and the form is correctly submitted.
> With MyFaces 1.1.2 and above
> -----------------------------------------
> * Resubmit the form correctly (using the submit button).
> ==> Nothing happens. No new token is generated, so no application logic gets invoked
and the workflow stucks.
> I attached a sample project which demoes the issue.
> -- EDIT: 
> I forgot to mention that with both MyFaces versions, I set the context-param "org.apache.myfaces.ALLOW_JAVASCRIPT"
to false. In theory, this shouldn't make a difference since I'm using HTTP POST just as the
javascript would do, but I think it's worth the hint.
> Regards,
> Mike

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://issues.apache.org/struts/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Mime
View raw message