Created
January 25, 2015 03:42
-
-
Save helambuapps/28fbccaff23a93c37b82 to your computer and use it in GitHub Desktop.
WAMP (Web Apps Messaging Protocol) Dynamic Authentication and Authorization example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from autobahn.asyncio.wamp import ApplicationSession | |
from autobahn.wamp import auth | |
from autobahn import wamp | |
import asyncio | |
# In a real life get this from your application database | |
USER = 'eddie' | |
PASSWORD = 'secret1' | |
class MyBackendComponent(ApplicationSession): | |
# In a real life get this from your application database | |
USERDB = { | |
'joe': { | |
'secret': 'secret2', | |
'role': 'backend' | |
}, | |
'peter': { | |
'secret': 'prq7+YkJ1/KlW1X0YczMHw==', | |
'role': 'frontend', | |
'salt': 'salt123', | |
'iterations': 100, | |
'keylen': 16 | |
}, | |
'jackie': { | |
'secret': 'forest123', | |
'role': 'authorizer' | |
} | |
} | |
@wamp.register('com.example.authenticate') | |
def authenticate(self, realm, authid, details): | |
print("authenticate called: realm = '{}', authid = '{}', details = '{}'".format(realm, authid, details)) | |
if authid in self.USERDB: | |
return self.USERDB[authid] | |
def onConnect(self): | |
print("connected. joining realm {} asser {} ...".format(self.config.realm, USER)) | |
self.join(self.config.realm, ["wampcra"], USER) | |
def onChallenge(self, challenge): | |
print("authentication challenge received: {}".format(challenge)) | |
if challenge.method == "wampcra": | |
if'salt' in challenge.extra: | |
key = auth.derive_key(PASSWORD.encode('utf8'), | |
challenge.extra['salt'].encode('utf8'), | |
challenge.extra.get('iterations', None), | |
challenge.extra.get('keylen', None)) | |
else: | |
key = PASSWORD.encode('utf8') | |
signature = auth.compute_wcs(key, challenge.extra['challenge'].encode('utf8')) | |
return signature.decode('ascii') | |
else: | |
raise Exception("don't know how to compute challenge for authmethod {}".format(challenge.method)) | |
@asyncio.coroutine | |
def onJoin(self, details): | |
res = yield from self.register(self) | |
print("{} procedures registered.".format(len(res))) | |
def onLeave(self, details): | |
print("onLeave: {}".format(details)) | |
self.disconnect() | |
if __name__ == '__main__': | |
from autobahn.asyncio.wamp import ApplicationRunner | |
runner = ApplicationRunner(url="ws://localhost:9000/ws", realm="realm1") | |
runner.run(MyBackendComponent) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from autobahn.asyncio.wamp import ApplicationSession | |
from autobahn.wamp import auth | |
from autobahn import wamp | |
import asyncio | |
USER = 'joe' | |
PASSWORD = 'secret2' | |
class MyBackendComponent(ApplicationSession): | |
@wamp.register('com.example.add2') | |
def add2(self, x, y): | |
return x + y | |
def onConnect(self): | |
print("connected. joining realm {} asser {} ...".format(self.config.realm, USER)) | |
self.join(self.config.realm, ["wampcra"], USER) | |
def onChallenge(self, challenge): | |
print("authentication challenge received: {}".format(challenge)) | |
if challenge.method == "wampcra": | |
if'salt' in challenge.extra: | |
key = auth.derive_key(PASSWORD.encode('utf8'), | |
challenge.extra['salt'].encode('utf8'), | |
challenge.extra.get('iterations', None), | |
challenge.extra.get('keylen', None)) | |
else: | |
key = PASSWORD.encode('utf8') | |
signature = auth.compute_wcs(key, challenge.extra['challenge'].encode('utf8')) | |
return signature.decode('ascii') | |
else: | |
raise Exception("don't know how to compute challenge for authmethod {}".format(challenge.method)) | |
@asyncio.coroutine | |
def onJoin(self, details): | |
res = yield from self.register(self) | |
print("{} procedures registered.".format(len(res))) | |
def onLeave(self, details): | |
print("onLeave: {}".format(details)) | |
self.disconnect() | |
if __name__ == '__main__': | |
from autobahn.asyncio.wamp import ApplicationRunner | |
runner = ApplicationRunner(url="ws://localhost:8080/ws", realm="realm1") | |
runner.run(MyBackendComponent) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"controller": { | |
}, | |
"workers": [ | |
{ | |
"type": "router", | |
"options": { | |
"pythonpath": [".."] | |
}, | |
"realms": [ | |
{ | |
"name": "realm1", | |
"roles": [ | |
{ | |
"name": "authenticator", | |
"permissions": [ | |
{ | |
"uri": "com.example.authenticate", | |
"register": true | |
} | |
] | |
}, | |
{ | |
"name": "authorizer", | |
"permissions": [ | |
{ | |
"uri": "com.example.authorize", | |
"register": true | |
} | |
] | |
}, | |
{ | |
"name": "backend", | |
"authorizer": "com.example.authorize" | |
}, | |
{ | |
"name": "frontend", | |
"authorizer": "com.example.authorize" | |
} | |
] | |
} | |
], | |
"transports": [ | |
{ | |
"type": "websocket", | |
"endpoint": { | |
"type": "tcp", | |
"port": 9000, | |
"interface": "127.0.0.1" | |
}, | |
"auth": { | |
"wampcra": { | |
"type": "static", | |
"users": { | |
"eddie": { | |
"secret": "prq7+YkJ1/KlW1X0YczMHw==", | |
"role": "authenticator", | |
"salt": "salt123", | |
"iterations": 100, | |
"keylen": 16 | |
} | |
} | |
} | |
} | |
}, | |
{ | |
"type": "web", | |
"endpoint": { | |
"type": "tcp", | |
"port": 8080 | |
}, | |
"paths": { | |
"/": { | |
"type": "static", | |
"directory": "../web" | |
}, | |
"ws": { | |
"type": "websocket", | |
"auth": { | |
"wampcra": { | |
"type": "dynamic", | |
"authenticator": "com.example.authenticate" | |
} | |
} | |
} | |
} | |
} | |
] | |
}, | |
{ | |
"type": "guest", | |
"executable": "/path/to/python/executable", | |
"arguments": ["authentication.py"], | |
"options": { | |
"workdir": "..", | |
"watch": { | |
"directories": [".."], | |
"action": "restart" | |
} | |
} | |
}, | |
{ | |
"type": "guest", | |
"executable": "/path/to/python/executable", | |
"arguments": ["authorization.py"], | |
"options": { | |
"workdir": "..", | |
"watch": { | |
"directories": [".."], | |
"action": "restart" | |
} | |
} | |
}, | |
{ | |
"type": "guest", | |
"executable": "/path/to/python/executable", | |
"arguments": ["backend.py"], | |
"options": { | |
"workdir": "..", | |
"watch": { | |
"directories": [".."], | |
"action": "restart" | |
} | |
} | |
} | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from autobahn.asyncio import wamp | |
from autobahn.wamp import auth | |
import asyncio | |
USER = 'peter' | |
PASSWORD = 'secret1' | |
class MyFrontendComponent(wamp.ApplicationSession): | |
def onConnect(self): | |
print("connected. joining realm {} asser {} ...".format(self.config.realm, USER)) | |
self.join(self.config.realm, [u"wampcra"], USER) | |
def onChallenge(self, challenge): | |
print("authentication challenge received: {}".format(challenge)) | |
if challenge.method == "wampcra": | |
if'salt' in challenge.extra: | |
key = auth.derive_key(PASSWORD.encode('utf8'), | |
challenge.extra['salt'].encode('utf8'), | |
challenge.extra.get('iterations', None), | |
challenge.extra.get('keylen', None)) | |
else: | |
key = PASSWORD.encode('utf8') | |
signature = auth.compute_wcs(key, challenge.extra['challenge'].encode('utf8')) | |
return signature.decode('ascii') | |
else: | |
raise Exception("don't know how to compute challenge for authmethod {}".format(challenge.method)) | |
@asyncio.coroutine | |
def onJoin(self, details): | |
res = yield from self.call('com.example.add2', 2, 3) | |
print("called procedure add2 {}".format(res)) | |
def onLeave(self, details): | |
print("onLeave: {}".format(details)) | |
self.disconnect() | |
if __name__ == '__main__': | |
from autobahn.asyncio.wamp import ApplicationRunner | |
runner = ApplicationRunner(url="ws://localhost:8080/ws", realm="realm1") | |
runner.run(MyFrontendComponent) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment