|
LATEST POSTS
Tuesday, February 16, 2010
Almost three years ago to the day, I concluded a post with this: I hate security and all software and hardware related to it, including but not limited to: anti-virus, spam, phishing, SSL, permissions, LDAP, NTLM, forms authentication, SecurID tokens, VPNs, swipe cards, PIN numbers, security deposits, car alarms, bike locks, and cell phones for seven-year-olds.I don't like that the major upgrade to Windows XP was a firewall that broke a bunch of apps. And that among IE7's features is not to let me into websites because I'm not smart enough to figure out if they're dangerous. And that Vista's main differentiation from XP is that it's harder to play my music. I will concede, however, that retinal scanners are pretty cool. Now, three years later and my position has changed slightly in that now I also don’t like OAuth, RSA, salts, Kerberos, MD5, SHA, IPSec, OpenID, HTTP sessions, cookies, cross-site request forgery, fingerprint scanners, parental controls, deadbolts, my mother’s maiden name, my favorite pet, the name of my elementary school, and “forgot my password” links that all but announce my password on Twitter. Again, though, retinal scanners rock. With that background, today’s topic is authentication with Google Web Toolkit. In the .NET world, I had my head somewhat wrapped around authentication. Or rather, I knew which code to cut and paste from previous apps to make it work in new ones. But having thrown myself headlong into GWT, I’ve had to actually research the concepts. A little. With an AJAX application like one built with GWT, there are actually two scenarios that require authentication: - Navigating to a page
- Performing an action on a page
Navigation has traditionally been fairly easy for me to work out. You fiddle with the web.config, add a login page, toss around a FormsAuthenticationTicket or two and call it a day. With GWT, this needs to be done via gwt-presenter. But I’ll leave it at that for now because I haven’t actually got around to doing that part of the authentication yet. Instead, I’ll focus on the second item: performing an action on a page. In GWT, I’m using gwt-dispatch, a command pattern implementation. It’s nice in that it provides a centralized interface for making RPC calls ‘twixt client and server. Nicer still is the latest version on the trunk which includes support for securing these calls. As David Peterson points out in this thread, there isn’t much you need to do in order to add security to your command calls. That said, it isn’t altogether obvious to a Java greenhorn how to implement it. So forthwith are my current thoughts in as plain English as I can realistically make it. The main issue I had when researching all this is that it seemed fairly academic. There is talk of sessions and session IDs and I couldn’t make the leap from that discussion to what I really wanted: to log in to the application. As I lamented on the OpenRasta forum, I can get a username and password from the screen, validate it against a database, and create a random session ID. What happens after that is still a little foggy. So here is the workflow as I see it now: - User enters username and password and clicks submit
- Login command is created and sent/dispatched to its appropriate handler on the server
- LoginHandler validates the user, creates a user object, and dumps it into the HTTP Session
- Server also creates a random session ID and dumps it into an appropriately-named cookie.
- Server returns login success
Next, the user performs some action that requires authentication: - Client creates an appropriate command and sends it to the server
- The session ID is attached to the command and sent to the server
- The server checks to see if the action being performed requires authentication.
- If not, it executes the action
- If so, it checks to see if a user has been added to the session. It also verifies that the session ID it received matches the one it generated earlier (by also checking the cookies)
- If the checks fail, throw an InvalidSessionException. Otherwise, execute the action.
- Back on the client, we use a custom AsyncCallback class that specifically checks for InvalidSessionException. If it catches one, we raise a Logout event which is configured elsewhere to redirect to the login page.
The session ID check seems kind of superfluous on the surface. But from what I gather, it’s necessary to prevent cross-site request forgery attacks. As far as I can tell, it’s not used for any other purpose. The vast majority of this is taken from various sources and I hope I remember them all. First is the Hupa, a web mail app written in GWT. Much assistance has come from the guy behind this site, which is shaping up to be one of the best tutorials I’ve seen in either Java or .NET. A good chunk of the explanation is from this post and I should note that most of the code in it has been incorporated into gwt-dispatch already. I had planned to incorporate some code in here but didn’t for a couple of reasons. One, this is kind of wordy and I’d rather do a follow-up that is more code-centric. Two, I haven’t finished the code. For now, the act of typing all this out has served it’s purpose in that it’s helped clarify things in my head. The nice thing is that much of this is already incorporated into gwt-dispatch already. I’m still a little fuzzy on where to implement the parts I need to implement (e.g. where do I check to see if an action can be performed anonymously?) but I have something that works. Which will serve as the basis for future posts. Kyle the Dispatched
Monday, October 01, 2007
One of my contracts involves what is essentially a document management system where users can search for legal documents based on metadata attributes as well as their contents. I've been working on it since before the days of SharePoint and even before Content Management Server was somewhat affordable. I mention this to cut off any comments that might say, "Why don't you just use a document management system?" It's in .NET and could benefit from migration to another platform. I'm not going to do it for reasons not worth mentioning. ACCEPT IT! There are two things worth posting about. Neither are new techniques by any stretch. The first is how to search the content and tie that into the metadata search. The second is how to restrict access to the documents (all in Word format) which are not restricted by IIS by default. Searching In order to search the contents of the repository, I'm using a technique that's been around for many moons. It starts with Microsoft Indexing Services (right-click My Computer, select Manage..., and it's under Services). I created a catalog and added the directory containing my documents. Easy enough. Now I have a catalog you can query from code using the Indexing Service query provider. I'd give you sample code but I don't have any; I don't query the catalog from code. It's no good to me on its own. I need to merge the results in with the metadata search in SQL Server. And rather than get one set of results from SQL Server and another from Indexing Services and merging them, I'm letting SQL Server do everything. To do this, I added a linked server to SQL Server: EXEC sp_addlinkedserver MyDocs, 'Index Server', 'MSIDXS', '<Indexing Service Catalog Name>' The first parameter can be whatever name you want. The next two are fixed and the last is the name of the Indexing Service catalog. From here, you can query the results directly from SQL Server and join them with any other query you want. For example: SELECT MetadataField1, MetadataField2, DocumentFileName FROM doc_metadata dl INNER JOIN OpenQuery( MyDocs, 'SELECT Filename FROM SCOPE( ) WHERE CONTAINS( Contents, ''<search term>'' ) ') q ON dl.DocumentFileName = q.Filename WHERE <filter conditions> And just like that, that squirrel's done, as my pappy used to say. The Indexing Service includes a bunch of properties you can return if you like, but for my poor man's document management system, all I need it for is to filter the list of search results. NOTE: Out of the box, the Indexing Service will index all forms of Office documents. For anything else, you'll need to find an appropriate filter that plugs into the service. Adobe makes one for PDFs but that's the extent of my knowledge. Restricting access to Word documents The application uses Forms Authentication to ensure you have appropriate access to the system. There are three roles: admin, subscriber, and guest (and an implied fourth role: ya can't git in). With the default forms authentication setup, anytime you navigate to an .aspx page, it will automatically redirect to the login page. This doesn't hold true for "unmapped" file extensions, such as image files or documents. By "mapped", I mean that IIS recognizes the extension and maps it to an ISAPI filter. Whenever IIS receives a request for a file with an extension it knows about, it filters the request through the corresponding ISAPI filter, which can then perform whatever funkiness it needs to before and/or after the request. Without getting too technical about the ASP.NET ISAPI filter (mostly 'cause I don't know too much about its inner workings including whether it actually *is* an ISAPI filter vs. an ISAPI application), I wanted any requests to Word documents to redirect to the login page if the user hadn't logged in. The same as any other page. So in IIS, I went to the application properties and added a mapping for .doc files (from the Virtual Directory tab, click Configuration..., then Mappings) to the ASP.NET executable (usually C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll or something akin). With that in place, users can no longer navigate directly to Word documents. Such requests will be re-directed to the login page. But there is one last requirement: guests aren't allowed to view documents. Easy enough: add a separate web.config to the documents folder restricting access only to subscribers and admins: <?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<authorization>
<allow roles="subscriber, admin" />
<deny users="*" />
</authorization>
</system.web>
</configuration>
Note: You can also accomplish this with a <location> element in your application's main web.config file. I picked this method because I have a feeling I'll be moving the documents out to a separate virtual directory altogether very soon.
And that's that. I shan't go into the details of setting up your roles but as you may have guessed from the web.config, that is a requirement in order for this to work. It's pretty straightforward Forms Authentication stuff so Google should be able to help you out easily enough. If not, my door is always open.
So with these two techniques, I now have a method for users to search the contents of documents without allowing them to actually open them. Maybe I can get a job at www.experts-exchange.com.
Kyle the Restrictive
Monday, February 19, 2007
The short version: Setting my clock to the current date fixes invalid security certificate errors in IE7 and log-in problems with MSN Messenger. The rest of this post is embellishment so that it can be picked up by a movie producer and turned into a film starring Neil Patrick Harris as the Coding Hillbilly and Scarlett Johansson as Mrs. Coding Hillbilly. A frantic call from Mrs. Hillbilly led to my edification of yourselves today: "Coding Hillbilly! He'p me, he'p me! I'sa gotta chekin' this har e-mail for'un my boss and I kint git into the Hotmail! Ya gotsta he'p me, Coding Hillbilly!" "Be right thar, Cabbage!" and I moseyed on over to her place as quick as the T-bird could fly. The error message: There is a problem with this website's security certificate. Now I've seen this often enough with the dawn of IE7 but this happened when she navigated to Hotmail of all places. Of course, she could continue on to the website with the nice calming red address bar at the top but it didn't inspire a lot of confidence that her computer was running at peak performance. At this point, the missus also pointed out that MSN Messenger was also puking all over her machine when she tried to log-in. Error 80048820 which is, as you could probably guess, security-related. The surprisingly effective help system in Messenger led me to a much prettier version of this page. Being a technically-minded hillbilly, I skimmed through the page looking for the most obtuse solution on the page and I went on my merry way re-registering DLLs and adjusting SSL options, none of which worked. Then option 3 stuck out at me: Verify the date and time settings on your computer. Huh? says I. Mrs. Hillbilly, who is hovering in a non-intrusive manner, notices my confusion: "Oh yeah, I had to change the clock for something else." A quick update to bring the date back a few months to February 19, 2007 and all is well again with our corner of the world. I wish no explanation as to why changing the clock affects MSN Messenger or security certificates. (I can make a partially-educated guess as to the latter.) Security is not my strong suit as anyone who has come to my house and found the doors wide open can attest to. I don't particularly care why they're related. All that matters is that someone else in the world does and he or she finds it fit to document his or her knowledge on the Internets. And on a concluding note, I hate security and all software and hardware related to it, including but not limited to: anti-virus, spam, phishing, SSL, permissions, LDAP, NTLM, forms authentication, SecurID tokens, VPNs, swipe cards, PIN numbers, security deposits, car alarms, bike locks, and cell phones for seven-year-olds.I don't like that the major upgrade to Windows XP was a firewall that broke a bunch of apps. And that among IE7's features is not to let me into websites because I'm not smart enough to figure out if they're dangerous. And that Vista's main differentiation from XP is that it's harder to play my music. I will concede, however, that retinal scanners are pretty cool. Not that I don't understand the need for it, which I very much do. I just hate the fact that we have to deal with it. But then, I'm far too much of an optimist to really understand the Prisoner's Dilemma that has led to everything from DRM to the "guilty until proven innocent" mentality that permeates our airport authority system.
Disclaimer
The opinions expressed herein are my own personal opinions and do not represent
my employer's view in any way.
Copyright © 2010 Kyle Baley. All rights reserved.
|
|
|
CATEGORIES
|
|
LATEST POSTS
POPULAR POSTS
|
|
ARCHIVE
| March, 2010 (1) |
| February, 2010 (8) |
| January, 2010 (2) |
| December, 2009 (3) |
| November, 2009 (2) |
| September, 2009 (5) |
| August, 2009 (4) |
| July, 2009 (2) |
| June, 2009 (5) |
| May, 2009 (6) |
| April, 2009 (5) |
| March, 2009 (6) |
| February, 2009 (2) |
| January, 2009 (6) |
| December, 2008 (5) |
| November, 2008 (2) |
| October, 2008 (5) |
| September, 2008 (9) |
| August, 2008 (5) |
| July, 2008 (7) |
| June, 2008 (6) |
| May, 2008 (11) |
| April, 2008 (13) |
| March, 2008 (13) |
| February, 2008 (12) |
| January, 2008 (19) |
| December, 2007 (16) |
| November, 2007 (8) |
| October, 2007 (23) |
| September, 2007 (15) |
| August, 2007 (8) |
| July, 2007 (6) |
| June, 2007 (11) |
| May, 2007 (19) |
| April, 2007 (14) |
| March, 2007 (3) |
| February, 2007 (4) |
| January, 2007 (7) |
| December, 2006 (5) |
| November, 2006 (9) |
| October, 2006 (11) |
| September, 2006 (14) |
| August, 2006 (11) |
| July, 2006 (15) |
| June, 2006 (8) |
| May, 2006 (10) |
| April, 2006 (12) |
| March, 2006 (3) |
| February, 2006 (7) |
|
|
|