Comments (5)
Hello @alex-zywicki,
The AsyncAPI specification supports adding security requirements to your API.
One can define the available security schemes under the components
section of the spec: https://www.asyncapi.com/docs/specifications/v2.2.0#componentsSecuritySchemes
Then, each of the server within the servers
object of the API, may reference any of the defined security schemes: https://www.asyncapi.com/docs/specifications/v2.2.0#serverObjectSecurity
See here for an example.
How can Asynction make use of this?
Within the components.securitySchemes
objects we can reference python functions that perform the required verification for each security scheme. Upon connecting to a namespace, Asynction can invoke the function(s) attached to the security scheme that is referenced by the chosen server. If the security function succeeds, its output will be validated against the provided scopes, and then passed as an extra token_info
argument to the connection handler. In the case of the server referencing multiple security schemes, Asynction should behave similar to Connexion: https://connexion.readthedocs.io/en/latest/security.html#multiple-authentication-schemes
Of course, in order to take advantage of this feature, one would need to provide the server_name
argument, so that Asynction can pick the appropriate authentication/validation functions.
An example YAML:
asyncapi: '2.2.0'
info:
title: Hello world application
version: '0.1.0'
servers:
production:
security:
- hello-oauth2: [write:hello_message]
channels:
hello:
publish:
message:
$ref: '#/components/messages/hello-msg'
x-handlers:
connect: foo.bar.hello_connect
components:
messages:
hello-msg:
name: hello msg
payload:
type: object
properties:
name:
type: string
sentAt:
$ref: '#/components/schemas/sent-at'
x-handler: foo.bar.hello_msg_handler
schemas:
sent-at:
type: string
description: The date and time a message was sent.
format: datetime
securitySchemes:
hello-oauth2:
type: oauth2
x-tokenInfoFunc: foo.bar.verify_token # function that will verify the user token and generate the `token_info` dictionary that includes `scopes`
flows:
implicit:
authorizationUrl: https://example.com/api/oauth/dialog
scopes:
write:hello_message: Send a hello message
read:hello_message: Send a hello message
The verify_token
token method of the foo.bar
module will receive the user token as an input, verify it, and produce a token_info
dictionary that includes the scopes
as an output. Then asynction would validate that the scopes that the server requires are included in the scopes of the token_input
. If validation succeeds, the token_info
dict will be passed to the connection handler, and the connection handler will be invoked (for the client to properly connect to the namespace)
from asynction.
@dedoussis I don't think I fully understand how the security schemes would be useful in a real world example. How do the security schemes map back to individual channels or messages on a channel. Or is the security only applied to access to the server itself. Would it be possible to allow users with a the correct scopes to access/use additional channels or messages than others who do not have said scope?
With API's I have written using connexion I tend to have the same "read", "write" scheme you show in your example with the read scope attached to http "GET" routes and the write attached to "PUT, POST, and DELETE" routes.
How would I do something similar?
from asynction.
@alex-zywicki Yes, atm the security schemes of AsyncAPI can only allow access to the server itself.
In Socket.IO authentication/authorization can only happen upon establishing connection to the server. A connection is established on the namespace/channel level. By default a Socket.IO client will use a single connection when connecting to the same server (even if it connects to multiple namespaces of that server). However, it is possible for the client to use the forceNew connection param, and force a separate connection per namespace. Would suggest you have a look in this paragraph of my article for some extra inisght on this.
Based on the above, there are 2 possible scenarios:
- The client does not use the
forceNew
param. In this case there is a single connection, which is on the server level (rather than the namespace level), and can be described by the existing security schemes of the specification (see my comment above). - The client does use the
forceNew
param, when connecting to multiple namespaces. In this case the security schemes would need to be defined at the channel level, rather than the server, and this is something that is not allowed by the current version of AsyncAPI. So you're right. We would need to propose an RFC to the specification and in the meantime we would need to come up with some specification extension.
Bear in mind that there is no need to include security on the message level, since authn/authz can only happen upon connection.
TL;DR: If you do not expect your clients to use the forceNew
option, then we can get away with it.
from asynction.
In Connexion, and in REST APIs in general, a new connection is established upon a request to each HTTP endpoint. Hence it is possible to customise the security schemes on the endpoint level.
from asynction.
Thanks for the contribution @alex-zywicki! This functionality has been released as part of version 0.5.0
. Closing the issue.
from asynction.
Related Issues (16)
- Multiple asyncapi yaml files HOT 5
- /docs does not work with asyncapi 2.2.0 HOT 1
- Per namespace security HOT 1
- python3.6 support HOT 4
- Docs viewer unhappy with Oauth2 Security scheme HOT 5
- Support for namespace classes HOT 1
- Bug with array payload validation HOT 6
- Support emitting events from an external process
- 1.0.0 release checklist
- docs: contribution section HOT 4
- Payload validator fails with oneOf in payload HOT 4
- All message payload and ack argument schemata should be tuples HOT 1
- CI should verify python version compatibility
- Document examples of using Asynction
- Incorporating asynction into existing flask API with socketio events HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from asynction.