Admin Area protected by simple scripted password in GWT

73 views
Skip to first unread message

Nickelnext

unread,
Jul 29, 2009, 1:00:36 PM7/29/09
to Google Web Toolkit
Hello everyone,

I'm trying to figure out how to create a small Admin Area protected by
a password (that could be hardcoded or stored in a xml file, it
doesn't matter) inside my application.

My application is basically a TabbedPanel that contains 4 or 5 panels,
some of them communicates with plain Java servlets and so on.

Now, what i need to do is a simple form that can authenticate the
admin and let him upload some files and do some other things. What i
wanted to do is to create another GWT class with some widgets inside,
but i don't know what is the best (or simply the easiest) way to do
that.

I read about using Basic or Form Tomcat Authentication, but in my case
is not possible (is it?) due to the fact that if I add the Admin Area
like a new Tab inside the TabbedPanel, with tomcat auth, every user
that would like to use my app should authenticate himself (what i
learned is that with tomcat auth you choose an entire page to
protect).

Yet, if i make another Module or try to set another Entry point
(didn't understand well how), using the Admin Area like another
application, would be more complex, and i'd prefer to create a unique
application.

I was wondering if i could use plain Java servlets, GWT servlets
(async ones), because i know that with php it would be easy to make
but i don't know how to mix php with gwt so i'd prefere to use another
method.

I hope i explained myself well, if you need any further explanation i
will give you as soon as possible.
Regards
Nickelnext

Trevis

unread,
Jul 29, 2009, 1:11:33 PM7/29/09
to Google Web Toolkit
I take it that regular users for your application dont have to
authenticate, but you want the admin to login and then show him or her
a different view (a view with an admin tab)?

The question is kind of broad, i mean allowing a user to login is
pretty much nuts and bolts stuff. You put together a widget with text
and password fields, give them a button to click (or respond to the
enter key) and then make an RPC call to the server where you'd
authenticate them (using a db, text file or hard coded value or
whatever you want). Once the RPC call returns successfully you can
rebuild the tabs or just add the admin tab.

Should be pretty straight forward. Do you have a more specific
problem?

Trevis

Nickelnext

unread,
Jul 29, 2009, 1:27:42 PM7/29/09
to Google Web Toolkit
Hello

You suggest that when the callback gets the Onsuccess and the user is
valid, i can simply add a new tab or panele or whatever making the
Admin Area visible?

Your solution would be perfect, and i thought of it yet but my
question is: isn't it easily hack-able? I mean, inside the javascript
that gwt compiles there would be also the admin area, so a malicious
user could, with some tricks, retrieve the content and do some ugly
things with my app, couldn't he?

What i mean is: is this easy and fast solution also secure? Would be
the part of the admin area untouchable if the user doesn't
authenticate himself or there should be a possibility? Because if i'm
not wrong, the solution you suggest isn't like one with, for example,
a PHP page that renders a new html page with the private content, but
the content is himself into the Application, cause the Admin Area tab
(or else) is in the client code (and so in whoever's open my app
browser).

Sorry for my bad bad english, hope you get the point.
Thank you!
Nickelnext

Trevis

unread,
Jul 29, 2009, 1:40:38 PM7/29/09
to Google Web Toolkit
Ah, I understand your concern.

Hm. Maybe someone with more GWT experience can chime in on this but
i'm thinking this. It's not like you have a simple hidden DIV in the
browser that you're deciding to show dynamically. You have a
javascript function that generates that div, which i'd imagine would
be a lot tricker to hack (though probably not impossible if the hacker
were properly motivated) Even still, what would the hacker have access
to at that point? He'd see the admin tab... but what could he do with
it? You should implement your security so that the admin RPC methods
also require some kind of authentication. This way, a determined
hacker may be able to see the tab but he still couldn't do anything
with it. Not knowing your exact application, this may have other
complications but that is the way that i'd probably be thinking of
doing it.

I'd love to hear some alternative solutions as i'm pretty much in the
same boat as you are. I'm porting my first major application to GWT
and i've been going with the assumption that server based security for
the admin RPC's combined with obfuscated javascript will give me a
similar level of security to what i would get by traditional means.
(though arguably better since there will be no history trail to the
admin pages left in the browser since gwt allows you to not cause any
browser history footprint that you don't deliberately generate)

Isaac Truett

unread,
Jul 29, 2009, 1:46:19 PM7/29/09
to Google-We...@googlegroups.com
http://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecurityFAQ

This FAQ and the Security for GWT Applications article it links to should help.

- Isaac

Trevis

unread,
Jul 29, 2009, 2:09:39 PM7/29/09
to Google Web Toolkit
Some good info in that link, Isaac, thanks.

"Do NOT attempt to use the Cookie header to transfer the sessionID
from GWT to the server; it is fraught with security issues that will
become clear in the rest of this article. You MUST transfer the
sessionID in the payload of the request. For an example of why this
can fail, see CrossSiteRequestForgery. "

Hm. Well, ok then... i guess i should heed that warning.

The article doesn't seem to directly address Nickelnext concern about
having the admin content already in the browser though. I mean, once
you compile the UI into javascript and the browser downloads it,
everything that the view does is there in the browser. It seems
pretty far out there that someone could use that obfuscated javascript
mischievously but that's what hacking is all about, so i hear!

Trevis

On Jul 29, 12:46 pm, Isaac Truett <itru...@gmail.com> wrote:
> http://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecur...
>
> This FAQ and the Security for GWT Applications article it links to should help.
>
> - Isaac
>

Isaac Truett

unread,
Jul 29, 2009, 2:16:20 PM7/29/09
to Google-We...@googlegroups.com
> The article doesn't seem to directly address Nickelnext concern about
> having the admin content already in the browser though. I mean, once
> you compile the UI into javascript and the browser downloads it,
> everything that the view does is there in the browser. It seems
> pretty far out there that someone could use that obfuscated javascript
> mischievously but that's what hacking is all about, so i hear!

Right. Anything you write in client-side code is there, albeit
obfuscated, for any user to see. So don't hard code the secret family
recipe, write an RPC (or JSON, or whatever service) to request it from
the server and send your session ID to the server in the request. And
you'll probably want to do it all over a secure socket.

Nickelnext

unread,
Jul 29, 2009, 7:48:58 PM7/29/09
to Google Web Toolkit
First of all thank you both for helping.

What the article suggests (i read it twice but without a big snippet
code i don't understand everything) is to:

- make a login box (user and pass)
- Call the server with RPC. The server answer back with a boolean
(Valid or NotValid) and a SessionID.
- The Client get the two vars, and when tries to do something in Admin
Mode (like uploading a file or something) sends also that sessionID.
If is still valid on the Server, it goes well, else it sends back an
error to the client.

The Admin area is still attached like Trevis said: with a RootPanel.add
(AdminArea) if the Callback got success.

So, the SessionID would prevent the fact that a malicious user could
reverse-eng the javascript code and use the admin area without any
permission, right?

If what i said is correct (or seems to be) then i'll try to write it
down and i'll let you know!

Nickelnext

Yanick

unread,
Jul 30, 2009, 7:57:12 AM7/30/09
to Google Web Toolkit
On Jul 29, 2:09 pm, Trevis <trevistho...@gmail.com> wrote:
> Some good info in that link, Isaac, thanks.
> [snip]
>
> The article doesn't seem to directly address Nickelnext concern about
> having the admin content already in the browser though.  I mean, once
> you compile the UI into javascript and the browser downloads it,
> everything that the view does is there in the browser.  It seems
> pretty far out there that someone could use that obfuscated javascript
> mischievously but that's what hacking is all about, so i hear!
>

Are you forgetting that we're talking about a GWT application here?
The admin content does NOT have to be downloaded with the rest of the
application. Let me explain my point:

Use case 1: a secure part of the application needs to be accessed
-------------------------------------------------------------------
1. anyone comes in, the entry point (server side) is invoked from the
app main page (index.html, whatever). (BTW: I haven't entirely looked
at the mechanism behind this, but I suggest that this is probably a
normal RPC or request being made of some sort by the initialization
process.)
2. browsing occurs normally until you reach an admin section, which
has not yet been loaded, but a login box as explained earlier.
3. user submits credential along with other identifying information as
needed (session cookie, whatever)
4. response comes back positive or negative (with other information,
like changed session id, whatever) as discussed
5. request is being made through a second RPC call at this point and
return some widget through the wire, replace the login by that widget
(add a new tab in your pane, whatever). Et voilà!

Options:
--------------
0.1. At any time, if the user wants to logoff (the logoff widget
should be displayed somewhere and always visible when the user is
logged in, perhaps a simple link/anchor with a click handler)
0.1.1. make an RPC request to the server and destroy the session data,
if any (clean session), no need to return anything
0.1.2. reload the entire application, or remove the admin widgets and
replace them with the original logon widget. End of scenario.
2.1. the user has already been identified, so the admin content
appears instead of the login box. End scenario
4.1. response comes back negative, display a pretty message of a
failed authentification attempt. Perhaps the server should return that
message, in case of anti-flooding or anti-DOS attack protection (I'm
thinking about a request cooldown time after n attempt, but I may be
going too far for this thread). End scenario.


Unless I'm mistaken, this is where I'm leading towards in my apps.
(I'm actually interested to know if I should change something in this
use case?)

Nickelnext

unread,
Jul 30, 2009, 8:48:38 AM7/30/09
to Google Web Toolkit
So you think I shouldn't load the admin area with the rest, and make
it visible when the user has logged in, but i should let user log in
and in response (within the asyncCallback) i send from the server to
the client the whole Panel, that would be added in the Gui.

Is it what you're saying? Now i'll try to do it but i don't know if
it's possible...

Nickelnext

unread,
Jul 30, 2009, 9:16:22 AM7/30/09
to Google Web Toolkit
I tried this way but i cannot make my AdminPanel (extends
verticalPanel) serializable, so i cannot transfer it like an object
through rpc...

jhulford

unread,
Jul 30, 2009, 11:20:43 AM7/30/09
to Google Web Toolkit
I think what they're saying is use a pair of deferred bindings for
your application. One for the standard use case and another for the
admin use case. The standard case should never reference the admin
tab and therefore the code that is contained in that tab or referenced
in it should be dead-code eliminated by the compiler pass that
generates the javascript/etc for the standard case binding option -
ergo users can't manipulate the javascript to get into the admin
section. For the admin case, it will contain the admin tabs and the
others. For users that authenticate as an admin you can set the
binding option (meta tag is easiest) on your host page to indicate to
the GWT loader that it should load the admin page instead of the
standard one.

Isaac Truett

unread,
Jul 30, 2009, 11:47:37 AM7/30/09
to Google-We...@googlegroups.com
@jhulford - That won't actually "secure" the admin UI, since anyone
can still download the UI by requesting that particular permutation.
**If the UI itself is sensitive** then you should consider other ways
of protecting it. But if, as is far more likely, it's the *data* that
is sensitive, then just let everyone download the admin UI along with
everything else (unless you feel like trying out runAsync) and then
make sure that your data services are secure (see the FAQ I posted
before).

@Nickelnext - That's right, you can't serialize a Widget object. What
you could do, if you wanted to go down that path, is to serialize data
that describes a Widget and write code on the client to create Widgets
based on that description. But as I stated in my reply to jhulford, I
would only do that after careful consideration which results in the
conclusion that my UI itself, the boxes and lines and pretty pictures,
are sensitive and warrant such measures. I have never come to that
conclusion in a GWT app. I always just secure the data.

- Isaac

Nickelnext

unread,
Jul 30, 2009, 12:40:22 PM7/30/09
to Google Web Toolkit
So, after reading your answers and over the web, i can assume that the
fastest way to make an admin area is to make a new module with
everything inside it and then use a Basic or Form Based tomcat
authentication.

That wouldn't be the best way, but for me it's the quickest.

So, assuming that i would choose this solution, is there a possibility
to make another page (i.e. my app is set on myapp.html, and i can
create admin.html in which gwt would compile the admin area) without
create a new module? I searched quite a lot but I can't find a good
tutorial for it.

Reassuming:
- The user opens my url, and the normal screen with tabs and things
appears.
- If user clicks on a link (admin.html), a new page will be loaded,
and it's the Admin.java that i create with gwt.
- Admin.html is protected with tomcat security, so there's no problem
on authentication, session or cookies.

Is it possible for you to give me a hint at how i can do it?
Thank you for your time, and sorry if i'm bothering with dumb
questions but i really can't find how to do that.

Nickelnext

Isaac Truett

unread,
Jul 30, 2009, 4:35:22 PM7/30/09
to Google-We...@googlegroups.com
> So, assuming that i would choose this solution, is there a possibility
> to make another page (i.e. my app is set on myapp.html, and i can
> create admin.html in which gwt would compile the admin area) without
> create a new module? I searched quite a lot but I can't find a good
> tutorial for it.

Yes. You could, for example, have <div id="myapp"></div> in myapp.html
and <div id="admin.html"></div> in admin.html and your EntryPoint
would check for the existence of one of those two divs and insert the
appropriate UI. But that doesn't do anything for security. You're
still downloading the UI for both together, because they're part of
the same module. Anyone could download the compiled JS, find the ID of
the element it's looking for, create an HTML page with that ID and
your JS, and see your admin UI. If you want it to be secure, you have
to keep it from reaching the client's computer unauthenticated.

Nickelnext

unread,
Jul 31, 2009, 4:46:32 AM7/31/09
to Google Web Toolkit
But, like i said, protecting admin.html with a tomcat rule like this:
<security-constraint>
<web-resource-collection>
<web-resource-name>Reports Browser</web-resource-name>
<url-pattern>admin.html</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>

<login-config>
<auth-method>BASIC</auth-method>
<realm-name>Protected Area</realm-name>
</login-config>

wouldn't be enough? Once i have protected my admin.html page with
this, the user can't download that page without permission.
Or am I missing/misunderstanding something?

Nickelnext

Isaac Truett

unread,
Jul 31, 2009, 8:08:53 AM7/31/09
to Google-We...@googlegroups.com
If all you're interested in protecting is that one file, then you're
set. My point is that all you're protecting is one file. You aren't
protecting your compiled GWT code at all.

Nickelnext

unread,
Jul 31, 2009, 10:08:43 AM7/31/09
to Google Web Toolkit
Oh. Now I got it. Thank you.

I thought that making two files would also mean that there were two
compiled javascripts, and the admin one could be protected with tomcat
policy.

So, now I'm on this.

I have a RPC LoginService that send me back a SessionID and a true
boolean if it goes well, or it invalidates my Session using
getThreadLocalRequest().getSession().invalidate();

If the boolean is true, the adminPanel is attached to the RootPanel.
In the AdminPanel there's a fileUpload widget and more.

When i try to upload a file, i send to the Java Plain Servlet that
handles upload also my SessionID got from the RPC. Now, the
UploadServlet checks if the two Sessions are the same, and works only
if the result of the comparison is true.

Is this a possible way to "secure" data like you said in your post
before?
Or is mine a stupid rambling speech?

Thank you for your time and advice
Nickelnext

Isaac Truett

unread,
Jul 31, 2009, 12:03:11 PM7/31/09
to Google-We...@googlegroups.com
Yes, it sounds like you're headed in the right direction now.
Reply all
Reply to author
Forward
0 new messages