fix issues in example, improve README

This commit is contained in:
Tobias Oberstein
2014-03-11 12:22:10 +01:00
parent 8bd6976e8a
commit ec66afdc04
3 changed files with 57 additions and 14 deletions

View File

@@ -1,9 +1,15 @@
WebSocket Authentication with Mozilla Persona
=============================================
This example shows how to authenticate WebSocket connections using [Mozilla Persona](http://www.mozilla.org/en-US/persona/) and HTTP Cookies.
This example shows how to authenticate WebSocket connections using [Mozilla Persona](http://www.mozilla.org/en-US/persona/) and HTTP Cookies. The example works with purely static Web pages and WebSocket only.
This example works with purely static Web pages and WebSocket only.
Tested with:
* Firefox 27
* Chrome 33
* IE11
Note: On IE11, using `localhost` as URL [does NOT work](https://groups.google.com/d/msg/mozilla.dev.identity/keEkVpvfLA8/2WIu7Q1mW10J). You must use `127.0.0.1` instead.
References:
@@ -22,3 +28,20 @@ and open
http://localhost:8080/
in your browser.
Here is the log output produced (on server) for a successful login:
oberstet@COREI7 ~/scm/tavendo/autobahn/AutobahnPython/examples/twisted/websocket/auth_persona (master)
$ python server.py
2014-03-11 12:20:05+0100 [-] Log opened.
2014-03-11 12:20:05+0100 [-] Running Autobahn|Python 0.8.4-3
2014-03-11 12:20:05+0100 [-] Site starting on 8080
2014-03-11 12:20:05+0100 [-] Starting factory <twisted.web.server.Site instance at 0x038113C8>
2014-03-11 12:20:23+0100 [HTTPChannel,1,127.0.0.1] Setting new cookie: 82vrA1drjZ_9lcBv
2014-03-11 12:20:36+0100 [HTTPChannel,1,127.0.0.1] Starting factory <HTTPClientFactory: https://verifier.login.persona.o
rg/verify>
2014-03-11 12:20:36+0100 [HTTPChannel,1,127.0.0.1] Authentication request sent.
2014-03-11 12:20:37+0100 [HTTPPageGetter (TLSMemoryBIOProtocol),client] Authenticated user tobias.oberstein@gmail.com
2014-03-11 12:20:37+0100 [HTTPPageGetter (TLSMemoryBIOProtocol),client] Stopping factory <HTTPClientFactory: https://verifier.login.persona.org/verify>
...

View File

@@ -15,6 +15,17 @@
var currentUser = null;
var sock = null;
var wsuri;
var persona_audience = null;
if (window.location.protocol === "file:") {
wsuri = "ws://127.0.0.1:8080/ws";
persona_audience = "127.0.0.1";
} else {
wsuri = "ws://" + window.location.hostname + ":8080/ws";
persona_audience = window.location.hostname;
}
var signinLink = document.getElementById('signin');
signinLink.onclick = function() {
navigator.id.request();
@@ -37,7 +48,7 @@
// 1. Send the assertion to your backend for verification and to create a session.
// 2. Update your UI.
if (sock) {
sock.send(JSON.stringify({cmd: 'AUTHENTICATE', assertion: assertion}))
sock.send(JSON.stringify({cmd: 'AUTHENTICATE', audience: persona_audience, assertion: assertion}))
}
},
onlogout: function() {
@@ -52,13 +63,6 @@
});
}
var wsuri;
if (window.location.protocol === "file:") {
wsuri = "ws://127.0.0.1:8080/ws";
} else {
wsuri = "ws://" + window.location.hostname + ":8080/ws";
}
if ("WebSocket" in window) {
sock = new WebSocket(wsuri);
} else if ("MozWebSocket" in window) {
@@ -78,7 +82,9 @@
}
sock.onmessage = function (e) {
msg = JSON.parse(e.data);
if (msg.cmd === 'AUTHENTICATED') {
userLabel.innerHTML = 'Authenticated as ' + msg.email;
@@ -96,6 +102,14 @@
watchPersona();
} else if (msg.cmd === 'AUTHENTICATION_FAILED') {
userLabel.innerHTML = 'Authentication failed: ' + msg.reason;
signinLink.disabled = false;
signoutLink.disabled = true;
watchPersona();
} else if (msg.cmd === 'LOGGED_OUT') {
window.location.reload();

View File

@@ -26,6 +26,7 @@ from twisted.python import log
from twisted.web.server import Site
from twisted.web.static import File
import autobahn
from autobahn.util import newid, utcnow
from autobahn.websocket import http
@@ -135,6 +136,7 @@ class PersonaServerProtocol(WebSocketServerProtocol):
## The client did it's Mozilla Persona authentication thing
## and now wants to verify the authentication and login.
assertion = msg.get('assertion')
audience = msg.get('audience');
## To verify the authentication, we need to send a HTTP/POST
## to Mozilla Persona. When successful, Persona will send us
@@ -149,7 +151,7 @@ class PersonaServerProtocol(WebSocketServerProtocol):
# }
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
body = urllib.urlencode({'audience': 'http://192.168.1.130:8080/', 'assertion': assertion})
body = urllib.urlencode({'audience': audience, 'assertion': assertion})
from twisted.web.client import getPage
d = getPage(url = "https://verifier.login.persona.org/verify",
@@ -175,13 +177,13 @@ class PersonaServerProtocol(WebSocketServerProtocol):
log.msg("Authenticated user {}".format(res['email']))
else:
log.msg("Authentication failed!")
self.sendMessage(json.dumps({'cmd': 'AUTHENTICATION_FAILED'}))
log.msg("Authentication failed: {}".format(res.get('reason')))
self.sendMessage(json.dumps({'cmd': 'AUTHENTICATION_FAILED', 'reason': res.get('reason')}))
self.sendClose()
def error(err):
log.msg("Authentication request failed: {}".format(err.value))
self.sendMessage(json.dumps({'cmd': 'AUTHENTICATION_FAILED'}))
self.sendMessage(json.dumps({'cmd': 'AUTHENTICATION_FAILED', 'reason': str(err.value)}))
self.sendClose()
d.addCallbacks(done, error)
@@ -221,6 +223,8 @@ if __name__ == '__main__':
log.startLogging(sys.stdout)
print("Running Autobahn|Python {}".format(autobahn.version))
## our WebSocket server factory
factory = PersonaServerFactory("ws://localhost:8080")
@@ -233,6 +237,8 @@ if __name__ == '__main__':
## run both under one Twisted Web Site
site = Site(root)
site.log = lambda _: None # disable any logging
reactor.listenTCP(8080, site)
reactor.run()