diff --git a/gracedb/alert.py b/gracedb/alert.py
index 4754d59944d03be1ccd8cfe435007bf2af22d590..3eb79d277bfad7d19ff80126a6324527f8ca3041 100644
--- a/gracedb/alert.py
+++ b/gracedb/alert.py
@@ -12,7 +12,7 @@ from django.core.urlresolvers import reverse, get_script_prefix
 from userprofile.models import Trigger, AnalysisType
 
 import glue.ligolw.utils
-import glue.lvalert.utils
+import ligo.lvalert.utils
 
 def issueAlert(event, location, temp_data_loc):
     issueXMPPAlert(event, location, temp_data_loc)
@@ -138,7 +138,7 @@ def issueXMPPAlert(event, location, temp_data_loc, alert_type="new", description
         stderr=STDOUT,
         env=env)
 
-    xmldoc = glue.lvalert.utils.make_LVAlertTable(
+    xmldoc = ligo.lvalert.utils.make_LVAlertTable(
                     location,
                     event.graceid(),
                     temp_data_loc,
diff --git a/gracedb/api.py b/gracedb/api.py
index 7079b50ab44a6d35db2adf5d5f2b14d9dcd13204..3f61ca4db53a5baef1db4201a1860f95562a38cd 100644
--- a/gracedb/api.py
+++ b/gracedb/api.py
@@ -5,7 +5,7 @@ from django.core.urlresolvers import reverse as django_reverse
 
 from django.conf import settings
 
-import simplejson
+import json
 
 from gracedb.models import Event, Group
 
@@ -326,7 +326,7 @@ def download(request, graceid, filename=""):
                 filename = os.path.join(dirname, filename)
                 rv[filename] = django_reverse(download, args=[graceid, filename])
 
-        response = HttpResponse(simplejson.dumps(rv), content_type="application/json")
+        response = HttpResponse(json.dumps(rv), content_type="application/json")
     elif os.path.isdir(filepath):
         response = HttpResponseForbidden("%s is a directory" % filename)
     else:
diff --git a/gracedb/middleware/auth.py b/gracedb/middleware/auth.py
index 0e2fb2d413c626b92140ab7f0a53205679365610..9e83a85f57cb73a11bc5d3fa8d0896d314041099 100644
--- a/gracedb/middleware/auth.py
+++ b/gracedb/middleware/auth.py
@@ -19,38 +19,42 @@ class LigoAuthMiddleware:
         ligouser = None
         user = None
 
-        principal = request.META.get('REMOTE_USER')
-        certdn = request.META.get('SSL_CLIENT_S_DN')
-        issuer = request.META.get('SSL_CLIENT_I_DN')
-
-        if not certdn:
-            try:
-                # mod_python is a little off...
-                # SSL info is in request._req
-                # Need to try/except because _req is
-                # not defined in WSGI request.
-                certdn = request._req.ssl_var_lookup ('SSL_CLIENT_S_DN')
-                issuer = request._req.ssl_var_lookup ('SSL_CLIENT_I_DN')
-                pass
-            except:
-                pass
-
         queryResult = []
-        if principal:
-            # Kerberos.
+        if not request.user.is_anonymous():
+            # Scott's middleware has set the user aready using shib.
+            # Let's add some more attributes.
+            principal = request.user.username
+            request.user.name = nameFromPrincipal(principal)
             queryResult = User.objects.filter(principal=principal)
-        elif certdn and certdn.startswith(issuer):
-            # proxy.
-            # Proxies can be signed by proxies.
-            # Each level of "proxification" causes the subject
-            # to have a '/CN=[0-9]+ appended to the signers subject.
-            # These must be removed to discover the original identity's
-            # subject DN.
-            issuer = proxyPattern.match(issuer).group(1)
-            queryResult = User.objects.filter(dn=issuer)
-        elif certdn:
-            # cert in browser.
-            queryResult = User.objects.filter(dn=certdn)
+        else:
+            # authenticate with certs
+            certdn = request.META.get('SSL_CLIENT_S_DN')
+            issuer = request.META.get('SSL_CLIENT_I_DN')
+
+            if not certdn:
+                try:
+                    # mod_python is a little off...
+                    # SSL info is in request._req
+                    # Need to try/except because _req is
+                    # not defined in WSGI request.
+                    certdn = request._req.ssl_var_lookup ('SSL_CLIENT_S_DN')
+                    issuer = request._req.ssl_var_lookup ('SSL_CLIENT_I_DN')
+                    pass
+                except:
+                    pass
+
+            if certdn and certdn.startswith(issuer):
+                # proxy.
+                # Proxies can be signed by proxies.
+                # Each level of "proxification" causes the subject
+                # to have a '/CN=[0-9]+ appended to the signers subject.
+                # These must be removed to discover the original identity's
+                # subject DN.
+                issuer = proxyPattern.match(issuer).group(1)
+                queryResult = User.objects.filter(dn=issuer)
+            elif certdn:
+                # cert in browser.
+                queryResult = User.objects.filter(dn=certdn)
 
         if queryResult:
             ligouser = queryResult[0]
diff --git a/gracedb/translator.py b/gracedb/translator.py
index b13f6a519df11caf3e8385291d021f1adf1e3159..39c71e4e3af6b749d23c10654ed7f8ab38ded1a7 100644
--- a/gracedb/translator.py
+++ b/gracedb/translator.py
@@ -7,13 +7,13 @@ from subprocess import Popen, PIPE
 from django.conf import settings
 
 import glue, glue.ligolw.utils
-from glue.gracedb.utils import InspiralCoincDef
-from glue.gracedb.utils import BurstCoincDef
+from ligo.gracedb.utils import InspiralCoincDef
+from ligo.gracedb.utils import BurstCoincDef
 
-from glue.gracedb.utils import insp_event_id_dict
-from glue.gracedb.utils import coherent_event_id_dict
+from ligo.gracedb.utils import insp_event_id_dict
+from ligo.gracedb.utils import coherent_event_id_dict
 
-from glue.gracedb.utils import populate_inspiral_tables, \
+from ligo.gracedb.utils import populate_inspiral_tables, \
                                populate_omega_tables,    \
                                populate_coinc_tables,    \
                                write_output_files
diff --git a/gracedb/views.py b/gracedb/views.py
index 4df0370776d72c7735a0115e1cc5d74c0dbf0d05..6f76d68c7922990f223bce96cc0f04cff9b148bd 100644
--- a/gracedb/views.py
+++ b/gracedb/views.py
@@ -31,7 +31,6 @@ MAX_QUERY_RESULTS = 1000
 
 GRACEDB_DATA_DIR = settings.GRACEDB_DATA_DIR
 
-import simplejson
 import json
 
 def index(request):
@@ -502,7 +501,7 @@ def ping(request):
             d['latest'] = {}
             d['latest']['id'] = latest.graceid()
             d['latest']['created'] = str(utc(latest.created))
-        d =  simplejson.dumps(d)
+        d =  json.dumps(d)
         response.write(d)
         response['Content-length'] = len(d)
     else:
@@ -575,7 +574,7 @@ def cli_search(request):
         for key in form.errors:
             d['error'] += "%s: %s\n" % (key, strip_tags(form.errors[key]))
     response = HttpResponse(mimetype='application/javascript')
-    msg = simplejson.dumps(d)
+    msg = json.dumps(d)
     response['Content-length'] = len(msg)
     response.write(msg)
     return response
@@ -626,7 +625,7 @@ def search(request, format=""):
                 'records' : 3,
                 'rows': rows
             }
-        msg = simplejson.dumps(d)
+        msg = json.dumps(d)
         response['Content-length'] = len(msg)
         response.write(msg)
 
@@ -821,7 +820,7 @@ def timeline(request):
                 'durationEvent':False,
               })
     d = {'events': events}
-    msg = simplejson.dumps(d)
+    msg = json.dumps(d)
     response['Content-length'] = len(msg)
     response.write(msg)
     return response
@@ -910,7 +909,7 @@ def flexigridResponse(request, objects):
             'rows': rows,
         }
     try:
-        msg = simplejson.dumps(d)
+        msg = json.dumps(d)
     except Exception, e:
         # XXX Not right not right not right.
         msg = "{}"
diff --git a/settings/__init__.py b/settings/__init__.py
index 0fcaf82e26ad5e2d845764e94a897f890b3fd582..f6419d7fa881f7e9d910226566e745834e93839a 100644
--- a/settings/__init__.py
+++ b/settings/__init__.py
@@ -29,6 +29,8 @@ configs = {
     '/home/branson/gracedbdev': 'branson',
     '/home/branson/gracedbdev/gracedb': 'branson',
 
+    "/home/gracedb/gracestage" : "stage",
+
 }
 
 
diff --git a/settings/default.py b/settings/default.py
index 3a93f89bb0d94aea402072336f879d6f80ab6bf1..e2bd3596e0601dd634e444a77683f4be6e0a20b3 100644
--- a/settings/default.py
+++ b/settings/default.py
@@ -158,15 +158,23 @@ TEMPLATE_CONTEXT_PROCESSORS = (
     'middleware.debug.LigoDebugContext',
 )
 
-AUTHENTICATION_BACKENDS = ('gracedb.middleware.auth.LigoAuthBackend',)
+AUTHENTICATION_BACKENDS = (
+    'gracedb.middleware.auth.LigoAuthBackend',
+    'ligodjangoauth.LigoShibbolethAuthBackend',
+    'django.contrib.auth.backends.ModelBackend',
+)
+
+SHIB_AUTHENTICATION_SESSION_INITIATOR = 'https://moe.phys.uwm.edu/Shibboleth.sso/Login'
 
 MIDDLEWARE_CLASSES = [
     'middleware.accept.AcceptMiddleware',
-    'gracedb.middleware.auth.LigoAuthMiddleware',
     'middleware.cli.CliExceptionMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'ligodjangoauth.LigoShibbolethMiddleware',
+    'gracedb.middleware.auth.LigoAuthMiddleware',
 ]
 
 ROOT_URLCONF = 'urls'
diff --git a/settings/production.py b/settings/production.py
index 208231e0bc53ecb56d925ca3af178daf9d9d6b4f..0eb78a83faeb2408e89b31b7cfd4b81183b0494f 100644
--- a/settings/production.py
+++ b/settings/production.py
@@ -1,3 +1,5 @@
+DEBUG = False
+TEMPLATE_DEBUG = DEBUG
 
 CONFIG_NAME = "PRODUCTION"
 
diff --git a/settings/stage.py b/settings/stage.py
new file mode 100644
index 0000000000000000000000000000000000000000..d3e0228917bc3f26e4630c5a5792bd6e890775b9
--- /dev/null
+++ b/settings/stage.py
@@ -0,0 +1,15 @@
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+CONFIG_NAME = "STAGE"
+
+SITE_ID = 3
+
+EMAIL_HOST = 'localhost'
+
+MEDIA_ROOT = '/home/gracedb/gracestage/static/'
+
+TEMPLATE_DIRS = (
+    "/home/gracedb/gracestage/templates",
+)
diff --git a/templates/gracedb/event_list.html b/templates/gracedb/event_list.html
index 8007cefa072203a4e8e52acfa26770ff1de6c5e9..405ffb9d4cf673b716e40d6fd948db466477f71f 100644
--- a/templates/gracedb/event_list.html
+++ b/templates/gracedb/event_list.html
@@ -48,7 +48,7 @@
             (
             {
             sortable: true,
-            url: '{% url search %}/flex?query={{rawquery|urlencode}}',
+            url: '{% url search %}flex?query={{rawquery|urlencode}}',
             datatype: 'json',
             mtype: "GET",
             colNames : ["UID", "Labels", "Neighbors (+/-5sec)", "Group", "Type", "Event Time", "Instruments", "FAR (Hz)", "Links", "Submitted", "Submitted By",
diff --git a/urls.py b/urls.py
index 6684532c10dab2594ce0911542463c2ce27032bc..a84933b55a41d5d291570e186a253fc326c440fa 100644
--- a/urls.py
+++ b/urls.py
@@ -40,4 +40,8 @@ urlpatterns = patterns('',
 
     url(r'^admin/', include(admin.site.urls)),
 
+    # For development only.  And only for old Django versions (like 1.2)
+    (r'^gracedb-static/(?P<path>.*)$', 'django.views.static.serve',
+        {'document_root': settings.MEDIA_ROOT}),
+
 )