JSF redirect doesn't stop page rendering - jsf

We're using JSF in a very simple way. All we're doing is implementing tags that contain a little Java code.
I have implemented a "security" tag that sends a 302 redirect back to the login page whenever the user isn't logged in:
// make them log in
ctx.getExternalContext().redirect("login.xhtml");
ctx.responseComplete();
The trouble is that the redirect() method doesn't stop the rest of the page being rendered. Tags that are further down the page are getting executed. This is a problem because non-logged-in users could see things they shouldn't if they had their browser ignore redirects.
How do I get responseComplete() to do what I thought it was supposed to do?

Its always better to implement the login related logic in a servlet filter, like below:
Implement a filter for the URL patterns that you want to secure
In the filter, check if the user is logged in (may be by just checking if Username/UserId is present in user session)
If the user is not logged in, redirect the user to a HTML based login page.
If the user is logged in, let the user access the resources.
There are a lot of ways (may be better than this) to implement this, but this is the most basic one.

Maybe you could use a flag to verify if the user is logged in.
Then, you can use the render=#{managedBean.logged} property in the tags you don't want to render.
This is just a workaround... can't really help too much with that amount of information you gave.

Try it!
ctx.getExternalContext().dispatch("login.xhtml");
ctx.responseComplete();

Related

XPages: Sign-In Form Mapping without separate DNS entry?

I've built an XPages with an integrated $$LoginUserForm integrated in the nsf.
Unfortunately my customer doesn't want to make a specific URL for the application (the process to make local DNS entries is apparently too time-consuming to consider).
AFAIK the field 'Web Site/Virtual Server' in the form 'Sign in' Form Mapping is only going to accept either an IP Number or a URL to identify the website, so I'm stuck with using the ugly server-standard form.
Or is there a workaround?
Andrew,
I have played quite a lot with these login forms. And I am afraid that you are right - if you want to use the builtin login redirection method you need to be able to map the login form in domcfg.nsf - either for all sites (which your client may not want) or for specific sites. I have found no way around this. Also it only works with a traditional form with the fields from the standard login form - no WebQuery-agents will run....
But you do have an alternative - if you want to control the login process yourself. Basically, you will need to test if the user is logged in (whereever that is needed) and redirect them to your own login page where you do an AJAX POST to the standard login form and read the credentials - or any login errors - and redirect to the page the user wanted. I do exactly that for an application written in XPages and Java :-)
I have defined an application viewhandler in facesconfig.xml that checks if the user is logged in - and redirects to my login page if login was required and the user had not yet logged in. To rely on Domino's security I have marked all XPages that the user can "reach" from a url as accessibly by anonymous users ($PublicAccess) and then the viewhandler checks for me - and redirects if necessary.
/John
If there is an internet site document available (even with an IP address defined) you should be able to map your login form in the domcfg to that IP/URL and it should be displayed. Did not test it but I think I did this once and it worked.

Passport login redirection

I'm using passport-facebook for logging into the site using facebook(the implementation is complete and working good) .Now , I want to redirect the user to a page containing a form which they are supposed to fill once they login from fb, and without doing it (that is without filling the form and submitting it) they shouldnt be able to access any other links on the site.
Here is the approach I thought of: Once the user logs in I would make a Database query inside the strategy to see whether they have previously submitted the data, if they have already submitted I would set the session.filledOrNot = true in the object which I'll be returning to the done callback and use this property to either allow them to proceed or redirect back the same page.
Is this a good approach?
This can be done in 2 ways.
1.You can either make the user the fill the form while sign up/registration(whatever you call it). If the user doesn't fill the form, don't let them sign up at all.
2.The second way is what you are suggesting. Let the user sign up with out filling the form and once the user logs in, check in your database where your condition "session.filledOrNot = true" is satisfied or not. The disadvantage is you need to make this query in every api request, not just the login request.

how can I create a user session for a specific private resource group on the frontend?

I have a full website with two contexts for two different languages. The only public page is the landing page of both languages. The rest should be private/protected. This I have achieved with resource groups and limits on the anonymous users.
On the landing page all the menu entries that are protected should be seen by the anonymous user and if clicked a popup with two login-forms should be displayed. These login-form are from other sites and will return if the users has permission or not when they've entered their credentials. And as long as this session exists the user should be able to view all pages if the user was approved of course.
My guess as a non modx- or php- pro is that I should check if a session exists when the landing page is loaded (and all sub-pages). If no user is logged in all links will point to the popup. The user then logs in, sends info to the external server and is redirected to the private/protected landing page if successful. And this is what I can't find any info about, probably because I'm not entirely sure what to look for.
I need one snippet that checks if a valid session exists for the protected pages, if not display the logins.
The other code I would need is something that creates the session for the user if the external login was successful. Should this be a snippet or just a php document on the server. And how can I start a session for the protected pages?
You could do this in two different ways:
Make a user-system that is not connected to Modx. I find this the easies and I've done this several times before. You'll need to make a table for users with usernames and password, and make an object out of it, so you can use xpdo to do the queries. With this system up and running, it would be no problem to include a snippet in every template to make sure the user is indeed logged in. If not, just redirect him to the correct frontpage/landingpage. This will require some coding, but as I said, it works like a charm.
Download the snippet http://modx.com/extras/package/login (by Spittingred, a true legend), and look at the code. I haven't used this Extra before, but I am pretty sure it uses the same user-system as Modx, and therefor you should be able to achieve what you want. I can't give you any more help than "look at the source and figure out how Spittingred did it".
MODX Revolution checks if the user is logged in when trying to access a protected page, but if you would like to check it manually this snippet would do:
if (!$modx->user->hasSessionContext($modx->context->get('key'))) {
$modx->sendUnauthorizedPage(); // redirect to the informative page for non-logged users
}
If you need to check for the user being logged in and display a login popup if not, then using the output modifier with simple user id check may work:
[[+modx.user.id:if=`[[+modx.user.id]]`:eq:=`0`:then=`Not logged in`:else=`logged in`]]
When it goes to the session creation for the users authenticated from outside of MODX site, I would suggest to write a snippet which checks the status from the eternal page and logs user in. This way the session checking will be ommited but still, the functionality goal should be achieved.

Session timeout and re-direction on login

On session timeout we re-direct to the login page and if the user logs back into the portal he gets re-directed to the page he was trying to navigate in the first place.
In our case, the re-directed page tries to fetch values from the session and it fails badly with exceptions and it works just fine when there is no dependency on pages which don't have any dependency on session variables.
What is the best way to handle the situation? Can we just redirect this to the home page instead, if so how to do this?
It depends on how much information you are storing in the session, as a guideline, you should always the "shortest" scope ever.
Probably your best option is to allow redirect only on stateless pages, so that it won't give you any problem about inconsistent state.
As for your last problem, take a look at this: redirecting-on-session-timeout-in-jsf-richfaces-facelet. Just set the tag to whatever you want.

Are multiple login locations a bad idea?

I initially designed my site to show a login box at the top of the page if the user was not authenticated (e.g. how reddit.com works).
I encountered a user who was having trouble with their browser's storage of their password because after a password change because their browser had stored their login information at different urls on the website. Even after the user typed correctly the new login information at one url, and the browser updated it, there would be other urls at which the browser had the incorrect login information.
This would also cause problems with sites that have a login box on their main page, and a special login page -- especially if the user front page login box is sent to the login page.
Is this a small enough case not to bother with, or should there only be one url at which a user can login to prevent this problem, especially for less technically-savvy audiences?
There should be one login page that every other page accessible sans login links to. It standardizes the process of logging in and reduces the kind of confusion your user experienced. It conforms to a convention that all the browsers are using with respect to saving passwords as well. Don't really see how you can go wrong that way.
Most sites use a single "sign in" button that takes you to the canonical login page.
If you want a signin box on every page that the browser can remember, consider using an iframe to hold the form.
I believe that if there is any way to use only ONE login location you should try to do it that way.
As you yourself said it's quite hard for browsers to determine what to do with stored passwords for sites with multiple login locations. There are possibly other problems and all of them are solved by having exactly one login location.
If you need to provide login from more places, just use redirection. But getting "in" your system should be done from one single place.
Just have one login page and have the other pages on your site linking to it. It keeps it simple for end users as there is only one page and easy for you to manage as you one have one login page.

Resources