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

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.

Related

How is an authentication follow designed?

For many applications that I've ever worked on. After logging successfully and session's still active, if users try to access signin/signup page by directly using browser address bar, they'll be redirected to dashboard or home page. I just follows some existing applications such as Goolge perhaps.
But what's the main reason of this flow? Does it raise any security risks if users can still access signin/sigup while their sessions are still active?
The decision to have separate login page or redirection of user to another page depends on the use case or requirement that you have for your website. It is directly related towards the functionality you want to provide to users.
It is mainly for bringing functional separation such that the login page is specifically for logging in and dashboard page or home page is to show the the account details or other related information of your home page. It also can be used for security purpose.
Functionally, having user login and dashboard page on same page can have its own challenges based on the other processing that is being done by you as per your use case. Consider a scenario where an email shall be sent whenever you login and also some additional processing is done based on the login procedure. Each refresh on the posted page would log the user back in. In such a case, every refreshment of the dashboard page would trigger an email and also does additional processing which may not be desired. In the perspective of security, based on your requirement, you may redirect URL based on PRG(Post-Redirect-Get) pattern to a restricted page or guest user page rather than having the main home page when an unauthenticated user logins or based on the subscription type of user.
It should also be noted that having a login mechanism integrated into the main page also has an advantage based on your website requirement as it provides the ability to login without losing the context of what the user is doing which is purely dependent on the requirement for your website. However, a separate login page has the advantage of being easier to implement and also for the pages that have sensitive information, you can simply redirect to the login page, rather than having to worry about rendering UI without the context of a valid session.
This is more of a usability feature than a security one. Developers put a bit of additional effort to implement stuff like this. Here is an example how they do it.
You should probably look into "OAUTH2" or similar authorization (beware not authentication) software, that might spread the light its about tokens and who might use them where and when. (pretty shady that's why im gonna leave that link here but you should really dig deeper for yourself)
https://docs.apigee.com/api-platform/system-administration/using-oauth2

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.

JSF redirect doesn't stop page rendering

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();

Storing username in cookie to increase cacheability?

Using: PHP, Symfony 1.4, Doctrine, sfGuard
I have a site where the majority of pages could be cached as full HTML pages. But there is the traditional 'user account toolbar' that appears at the top right of most sites (shows the logged in username, logout link etc.)
This obviously prevents the page from being fully cached as HTML so I plan on outputting the page as standard HTML and adding in the username etc. after page load, via Javascript.
When the user logs in, I will create an extra cookie storing just the username. Javascript can then check if the cookie exists and create the account toolbar. The username will only be used for display purposes. In order to actually log in the users will have to go through the normal login page, using their password etc.
I've searched for blog posts etc on this but not found much. Can anyone identify any security or other concerns with this?
As long as the user name is only used for display purposes you should be golden. Alternatly you could use an XHR to grab the username from PHP's $_SESSION.
My concerns are that you'd be using the user name to authenticate that user. Or using the user name as a key to access your cache, where by changing the user name would give an attacker access to another's cache.
You should never, ever store anything sensitive in a cookie. To me, that includes usernames.

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