http://example.com/yourapp/pageX.xhtml?param1=value1
, the application should be able to redirect the user to the same page and, at the same time, retain the complete query string at the end of the requestURL
.In this tutorial, I will assume that your application has a login bar on top of all pages. Based on this assumption, your application needs to handle the following 3 scenarios:
- The user logs in directly from the top login bar and succeed.
- The user entered wrong password, etc.
- The user was forwarded or redirected to the
login.xhtml
page when they tried to access a restricted resource.
For the first scenario, one very important thing to note is that when a user clicks the
Login
button, the requestURL
for that click will not carry the original query string anymore. As a consequence, if you capture the requestURL
at this point, it's too late and you will only have http://example.com/yourapp/pageX.xhtml
. In other words, to get the full requestURL
, you need to capture the requestURL
even before the user clicks the Login
button. To achieve this goal, in your templates, you need to define the following <f:event>
:
This is our
@SessionScoped
managed bean:
And this is the
Login
managed bean:
For the second scenario, users will usually arrive at the
Done? No, this is a double-trap :O! We still need to take care of the situation in which the user didn't surf any pages before logging in.
login.xhtml
page where you display a big & fat error message. At this point, you might have jumped into your own trap if you have also included the above <f:event>
inside your login.xhtml
page. The event would be triggered and your originalURL
property would be wrongly updated to the login page's URL. So, in brief, you must NOT include the above <f:event>
inside your login.xhtml
page.Done? No, this is a double-trap :O! We still need to take care of the situation in which the user didn't surf any pages before logging in.
For the third scenario, you need to understand the difference between a
forward
and a redirect
. When a user is forwarded to the login.xhtml
page, the requestURL
will still be http://example.com/yourapp/pageX.xhtml?param1=value1
even though the content of the view is from the login.xhtml
page. On the other hand, if the user is redirected, the requestURL
will become http://example.com/yourapp/login.xhtml
.
In case the user was redirected, I will assume that you're using a homegrown
Filter
to perform the login check and redirect users afterward. In this situation, you need to include the original requestURL
as a parameter in the redirecting URL:
After that, you need to update your
LoginBean#init()
function to retrieve the parameter in both cases as following:
I am using the same example of using socialauth for facebook login for jsf web application. However i am not able to execute the application successfully because of the below issue.
ReplyDelete{
"error": {
"message": "redirect_uri isn't an absolute URI. Check RFC 3986.",
"type": "OAuthException",
"code": 191
}
}
Please help me in resolving this issue. Provide me your mail id to send the complete WAR file for you to look into
SocialAuth will generate a proper link for you to redirect the user to for logging in. I think you should try to print out the link to debug :)... And sorry, at the moment, I'm a bit busy. Please upload your WAR to some repository and leave the link here. I will take a look when I have more spare time :D...
DeleteThanks for posting this. I've been wanting to switch to container based authentication but really don't have time. Your post has allowed me to tweak my existing filter based authentication to redirect users to the URL they initially tried to visit.
ReplyDeleteI do have a problem when people try to visit http://example.com/myapp. This takes them to the login page if they aren't already logged in. But the originalURL is set to /myapp/ so they get taken back to the login page even after a successful login. After they login a second time, they are taken to the welcome page. I'm trying to figure out a tidy way to avoid this, probably by adding some extra checks in my filter class, for instance by checking that requestURI != contextPath (plus an extra slash).
I think the simplest solution would be not to include the "" in any pages that do not require redirecting to. For instance, the Login page should not contain the event. The effect is that no "originalURL" will be captured.
Delete