How to restrict some module of GWT based application from accessing it directly via url - security

I have to secure a section of my GWT based application from accessing it directly via some url.
Actually there is an index page which is login page. The use gives credentials and enters into the app (the module to be saved).
Currently what I am doing is that when a user logs in I save his username into session ( session.setAttribute(“username”, username) ) and load the required view of user.
Now whenever user navigates the application I call a method via RPC which checks if the “username” attribute is set or not in the session; if it is set then method returns true and false otherwise.
And of course if it returned false then I load the index view of application (which says user to log in).
Now I have to call this method before I load any module which should be accessed by loggined user only to restrict illegal access via url etc.
From the scenario given above kindly guide me; if it is the right strategy to secure some module. Or are there other good ways to do the same thing.
Cheers!
Raza

While your approach would work, I feel a Servlet Filter is the best place to authorize web server requests. Since all the requests have to pass through the filters before hitting the servlet, this is the best place to make proceed/abort/redirect decisions, based on the url pattern and your session attributes.
Having ( /* ) security filters also ensures that all your web app requests pass through the authorization test first, leaving the servlet code to just do the business stuff.

Related

is authentication with client side rendered app and sessions possible?

No matter how I reason about it, it seems as if there is no secure way of implementing a client side rendered single-page-application that uses/accesses information on sessions for authentication, either via cookies, without severe compromise in security. I was mainly looking to building a React app, but it seems as if I will need to build it with SSR for a relatively secure version of authentication.
The use case that I'm especially thinking of is where the user logs in or registers and then gets a cookie with the session id. From there, in a server side implementation, I can simply set up conditional rendering depending on whether the server stored session has an associated user id or not and then pull the user information from there and display it.
However, I can't think of a client-side rendered solution where the user can use the session id alone on the cookie that isn't easily spoofable. Some of the insecure implementations would include using browser storage (local/session). Thanks.
I think the major issue here is that you are mixing the two parts of a web page (at least according to what HTML set out achieve) and treating them both as sensitive information.
You have two major parts in a web page - the first being the display format and the second being the data. The presumption in client side rendering / single page applications is that the format itself is not sensitive, and only the data needs to be protected.
If that's the case you should treat your client-side redirect to login behavior as a quality of life feature. The data endpoints on your server would still be protected - meaning that in theory an unauthenticated user could muck about the static HTML he is being served and extract page layouts and templates - but those would be meaningless without the data to fill them - which is the protected part.
In practice - your end product would be a single page application that makes requests to various API endpoints to fetch data and fill in the requested page templates. You wouldn't even need to go as far as storing complex session states - a simple flag notifying the client if it is authenticated or not would suffice (that is beyond what you would normally use for server-side authentication such as cookies or tokens)
Now let's say I'm a malicious user who is up to no good - I could "spoof" - or really just open the browser dev tools and set the isAuthenticated flag to true letting me skip past the login screen - now what would I do? I could theoretically navigate to my-service/super-secret without being redirected locally back to the login page on the client side - and then as soon as the relevant page tries to load the data from the server with the nonexistent credentials it would fail - best case displaying an error message, worst case with some internal exception and a view showing a broken template.
So just to emphasize in short:
A. If what you want to protect is your TEMPLATE then there is no way to achieve this clientside.
B. If what you want to protect is your DATA then you should treat gating/preventing users from navigating to protected pages as a quality of life feature and not a security feature, since that will be implemented on the server when serving the data for that specific page.

Access without Logging in

Im using GWT, GAE to make a web app.
I looked at a bunch of tutorials regarding implementing a login system but most of those tutorials implement it so it's mandatory to login to access the web app. How would I go about making it so that anyone can access the app but if they want to use account specific functionality, they they have the option of signing up for an account.
There are two parts to it.
First, in your client code you check if a user is logged in. If so, you allow access to the "closed" parts of the app. If not, you show a link/button to login and hide tabs/views that are accessible to authorized users.
Second, in your server code you specify which requests do not require authentication and which do require it. This is necessary if a user somehow figures out how to send a request without using your client code.
For example, in my code some requests have checkSession() called at the very beginning. If no authentication object is found for this user in session, this method throws LoginException to the client. If the authentication object is present, the request continues to execute normally and returns requested data to the client.
Further to Andrei's answer, if you want a framework to manage the sessions for you, you can use GWT-Platform, which has an excellent Gatekeeper feature.
I use it for mine and I have a LoggedInGatekeeper class. Simply add #UseGatekeeper(LoggedInGatekeeper.class) to the constructor of each presenter proxy and it checks if the user is logged in. If you want anyone to be able to access that page simply annotate with #NoGatekeeper. Easy!
It takes a bit of setting up but it's a great MVP framework. There are maven archetypes and samples etc.
Hope this helps.

How to probe for authorized access on the client side

So far I have mainly been using a single asp.net app metaphor where the razor pages are served together with the data from the same app, so I can protect certain controller actions for the ui and data controller actions using the same security.
My new app has a completely independent api web site (using servicestack) and a different asp.net UI app that consumes the api. Right now the two apps sit on the same server, but I want to support the ability for anybody to write a UI app that consumes my data, so the app could sit anywhere and could be a php app all I care.
The new UI uses razor and MVC but it is really a fully client side app, which requests data from the api site.
So, the problem is right there. I am used to automatically redirecting a page from the server side to the login when someone hasn't logged in yet. My UI's server side has no concept of the login situation of the api web site.
The best I can do right now is, at the begging of ANY UI page's load, to do a lightweight ajax call to the api web site, to get the current user info. If it's null, I do a client side document.location.href = .
This works, but has issues, primarily it causes a lot of client side busy ui stuff. An initial version of the UI loads empty (no data), then an awkward redirect to the login page happens. The client side app becomes chatty - every page that loads does an additional call to the api site. The server side redirect is clean because the first page you see is either the UI page that you already have access to or the login page.
My first question is, what is the best practice to do this kind of stuff? My second question is, is there a client side cookie on my UI page that deterministically tells me I am logged in to the api site? I inspected the cookies on a UI page before and after the login that sets the security to the api site and the cookies seem to be the same. My third question is - is there some kind of security actionfilter I can write for my UI mvc site, which somehow magically determines from the cookies of the request, whether the UI is currently logged in to the api site and if it is, it lets the request serve the page, if not, it does the sever side redirect to the login page.
Thanks
Edit:
Scott - thanks so much for the detailed explanation. One clarification - i use mvc only to really serve my client side html. I use all knockoutjs and Ajax calls to servicestack to render the data. My question is really about how to react to Ajax calls that return security exceptions and how to avoid presenting an empty html ui because the user is not logged in. My login page authenticates directly from html to ss bypassing the mvc part. It's not an spa where I can keep a single client side login state that applies to all views of the spa. There are multiple cshtml pages that all need to probe for login in order to not load empty and redirect to the login page...
So the MVC just serves the blank template, that includes the knockout js that will call the API to populate it? I believe this flow shows how your current pages are testing for a session using a lightweight ajax call to the api.
The problem with that approach as you have noted is that it has overhead, and a noticeable delay if there isn't a session.
Solution:
You can't test for the ss-id cookie in your JavaScript client application because of the origin difference. Knowing this cookie exists would give you an indication of whether a user might have a valid session. But seeing you can't access it, you have to work around this. When your login page successfully creates a session by calling the API, you should have the success method create a cookie that denotes that you have a session. Such as a hasSession cookie.
You can check for this existence of this cookie on each page load. It doesn't involve a server trip to verify it. If that cookie has the same expiration policy as the ServiceStack API cookie, then it should stay in sync.
The initial cshtml page state should hide the unpopulated page form contact using CSS, and show a loading indicator until the data is loaded from the API.
When the page first loads it should check if the hasSession cookie exists? If it doesn't then it shouldn't make any API calls, and should redirect immediately login.
How would I know that I can invoke ajax calls and succeed without making a test call?
You should just assume you have a session ss-id cookie if you have the hasSession cookie as you must have logged in successfully to get it. So make you call for the page data. If you get data back from the call and not a 401 exception then populate the form, and display it by altering the CSS.
If you got a 401 redirect to the login screen, and delete the hasSession cookie. The user won't have seen a blank unpopulated form because the CSS prevented this. They get a loading indicator while waiting, a perfectly reasonable state.
The 401 Authorization error should only occur once, and redirect to login, and that shouldn't even happen if your hasSession and the ss-id cookie expiration remain in sync.
I am just confused why you are trying to change the ServiceStack attributes now, subclassing [Authorize]. You shouldn't need to change the behaviour of the API.

When trying to create a SSL connection with LWP::UserAgent, what do I use for realm?

I've started a project to scrape my work's employee website to scrape the user's (in this case, mine) schedule and munge the data onto a google calendar. I've decided to go with Perl with LWP.
The problem is this, when trying to set up SSL negotiations I don't know what do put for the 'realm'.
For example: (http://www.sciencemedianetwork.org/wiki/Form_submission_with_LWP,_https,_and_authentication)
# ...
my $ua = new LWP::UserAgent;
$ua->protocols_allowed( [ 'http','https'] );
$ua->credentials('some.server:443',**'realm'**,'username','password');
# ...
I've looked at everything my browser can tell me and at a wireshark packet capture trying to find anything but to no avail. I assume that second argument to credentials() isn't optional.
Where do I find the 'realm' I'm supposed to use?
The credentials are for the HTTP authentication protocol (RFC 2617) (Wikipedia).
The server can challenge the client to authenticate itself. This response contains a string called “realm” which tells the client for what authentication is required. This allows the same server under the same domain to request authentication for different things, e.g. in a content management system where there might be an “user password” and an “administrator password”, which would be two different realms.
In a browser, this realm would be displayed alongside the username and password box which allows the user to type in the correct password.
To discover the realm, navigate to a page which requires authentication and look for the WWW-Authenticate header.
Note that HTTP authentication has become quite uncommon, with session cookies being used more often. To deal with such an authentication scheme, make sure that your LWP::UserAgent has an attached cookie storage, and then navigate through the login form before visiting your actual target page. Using WWW::Mechanize tends to make this a lot easier.

j_security_check dilemma - work around

Before implementing j_security_check using MySQL realm authentication in my web app. I had the form info sent to a servlet (action controller) which would authenticate the user and then add some info regarding the user to the session object. Other servlets could then make use of this session object. After implementing j_security_check I dont know how to add the details of the login to the session object since j_security_check is being called instead of my controller and then it forwards to the requested page. Its like as soon as a user signs in - the data specified on the form is needed to create the session object , however i currently cant find any way of accessing the data submitted since its being passed to j_security_check. I tried using filters but i cant seem to read the submitted data directed towards j_security_check.Any suggestions on what i should do (I just want to set a session object as soon as a user signs in)
The only information you can get in j_security_check is username and password. I don't see a use case of storing password in the session.
But, anytime the username can be obtained using HttpServletRequest.getRemoteUser()

Resources