使用 Crossbar/Autobahn 用于用户通知的身份验证?
Authentication to use for user notifications using Crossbar/Autobahn?
我目前正在尝试通过 Crossbar/Autobahn 使用 Websockets 实现用户通知系统。我已经完成了多项测试并阅读了文档,但是,我不确定是否有解决以下工作流程的方法:
- 用户使用网络应用程序登录——这是通过 JWT 完成的
- 前端建立到 运行
crossbar
实例的 websocket 连接。
- 前端尝试订阅专门用于用户通知的 URI:即
com.example.notifications.user.23
或 com.example.user.23.notifications'. Where
23` 是用户 ID。
- 检查用户的 JWT 以查看是否允许用户访问订阅。
- 当生成 activity 并引起通知时,后端会发布用户特定的 URI。
对于第3步,我无法判断当前支持的auth方法是否有我需要的。理想情况下,我想要一个可以自定义的 auth 方法(以便在 Crossbar 中实现 JWT 身份验证器),我可以将其应用于 URI 模式,但不向订阅用户提供对整个模式的访问权限。这已通过动态身份验证方法部分解决,但缺少后半部分:
例如(我理想的工作流程):
- 用户尝试订阅 URI
com.example.user.23.notifications
。
- URI 匹配
com.example.user..notifications
(http://crossbar.io/docs/Pattern-Based-Subscriptions/ 中的通配符模式)
- 验证令牌已验证,用户被授予 仅
com.example.user.23.notifications
的访问权限。
以上是否可以通过简单的方式实现?据我所知,只有当我以某种方式生成一个包含所有用户 ID 的 URI 排列的 .crossbar/config.json
时才有可能……并为每个新用户自动生成一个新配置——这完全不合理解决方案。
感谢任何帮助!
使用授权方。
参见 http://crossbar.io/docs/Authorization/#dynamic-authorization
为在 joining/authenticating 时分配的会话的用户角色注册一个动态授权者:
{
"name": "authorizer",
"permissions": [
{
"uri": "com.example.authorize",
"register": true
}
]
},
{
"name": "authenticator",
"permissions": [
{
"uri": "com.example.authenticate",
"register": true
}
]
},
{
"name": "user",
"authorizer": "com.example.authorize"
},
...
"components": [
{
"type": "class",
"classname": "example.AuthenticatorSession",
"realm": "realm1",
"role": "authenticator",
"extra": {
"backend_base_url": "http://localhost:8080/ws"
}
},
{
"type": "class",
"classname": "example.AuthorizerSession",
"realm": "realm1",
"role": "authorizer"
}
]
写一个class
class AuthorizerSession(ApplicationSession):
@inlineCallbacks
def onJoin(self, details):
print("In AuthorizerSession.onJoin({})".format(details))
try:
yield self.register(self.authorize, 'com.example.authorize')
print("AuthorizerSession: authorizer registered")
except Exception as e:
print("AuthorizerSession: failed to register authorizer procedure ({})".format(e))
def authorize(self, session, uri, action):
print("AuthorizerSession.authorize({}, {}, {})".format(session, uri, action))
if session['authrole'] == u'backend': # backnend can do whatever
return True
[Authorization logic here]
return authorized
我目前正在尝试通过 Crossbar/Autobahn 使用 Websockets 实现用户通知系统。我已经完成了多项测试并阅读了文档,但是,我不确定是否有解决以下工作流程的方法:
- 用户使用网络应用程序登录——这是通过 JWT 完成的
- 前端建立到 运行
crossbar
实例的 websocket 连接。 - 前端尝试订阅专门用于用户通知的 URI:即
com.example.notifications.user.23
或com.example.user.23.notifications'. Where
23` 是用户 ID。 - 检查用户的 JWT 以查看是否允许用户访问订阅。
- 当生成 activity 并引起通知时,后端会发布用户特定的 URI。
对于第3步,我无法判断当前支持的auth方法是否有我需要的。理想情况下,我想要一个可以自定义的 auth 方法(以便在 Crossbar 中实现 JWT 身份验证器),我可以将其应用于 URI 模式,但不向订阅用户提供对整个模式的访问权限。这已通过动态身份验证方法部分解决,但缺少后半部分:
例如(我理想的工作流程):
- 用户尝试订阅 URI
com.example.user.23.notifications
。 - URI 匹配
com.example.user..notifications
(http://crossbar.io/docs/Pattern-Based-Subscriptions/ 中的通配符模式) - 验证令牌已验证,用户被授予 仅
com.example.user.23.notifications
的访问权限。
以上是否可以通过简单的方式实现?据我所知,只有当我以某种方式生成一个包含所有用户 ID 的 URI 排列的 .crossbar/config.json
时才有可能……并为每个新用户自动生成一个新配置——这完全不合理解决方案。
感谢任何帮助!
使用授权方。
参见 http://crossbar.io/docs/Authorization/#dynamic-authorization
为在 joining/authenticating 时分配的会话的用户角色注册一个动态授权者:
{
"name": "authorizer",
"permissions": [
{
"uri": "com.example.authorize",
"register": true
}
]
},
{
"name": "authenticator",
"permissions": [
{
"uri": "com.example.authenticate",
"register": true
}
]
},
{
"name": "user",
"authorizer": "com.example.authorize"
},
...
"components": [
{
"type": "class",
"classname": "example.AuthenticatorSession",
"realm": "realm1",
"role": "authenticator",
"extra": {
"backend_base_url": "http://localhost:8080/ws"
}
},
{
"type": "class",
"classname": "example.AuthorizerSession",
"realm": "realm1",
"role": "authorizer"
}
]
写一个class
class AuthorizerSession(ApplicationSession):
@inlineCallbacks
def onJoin(self, details):
print("In AuthorizerSession.onJoin({})".format(details))
try:
yield self.register(self.authorize, 'com.example.authorize')
print("AuthorizerSession: authorizer registered")
except Exception as e:
print("AuthorizerSession: failed to register authorizer procedure ({})".format(e))
def authorize(self, session, uri, action):
print("AuthorizerSession.authorize({}, {}, {})".format(session, uri, action))
if session['authrole'] == u'backend': # backnend can do whatever
return True
[Authorization logic here]
return authorized