Coder Social home page Coder Social logo

snapp-incubator / soteria Goto Github PK

View Code? Open in Web Editor NEW
10.0 5.0 0.0 12.55 MB

Snapp EMQ Authentication based on EMQ HTTP Plugin

License: GNU General Public License v3.0

Dockerfile 0.41% Go 97.66% Smarty 1.93%
authentication authorization cloud emqx mqtt

soteria's Introduction

Soteria

GitHub Workflow Status Codecov GitHub repo size GitHub tag (with filter) GitHub go.mod Go version (subdirectory of monorepo)

Introduction

Soteria is responsible for Authentication and Authorization of every request sent to EMQ. The following configuration in HOCON format, configure EMQ to use HTTP Service for Authentication and Authorization.

{
    mechanism = password_based
    backend = http
    enable = true

    method = post
    url = "http://127.0.0.1:8080/v2/auth"
    body {
        username = "${username}"
        password = "${password}"
        token = "${username}"
        clientid = "${clientid}"
    }
    headers {
        "Content-Type" = "application/json"
        "X-Request-Source" = "EMQX"
    }
}
{
    type = http
    enable = true

    method = post
    url = "http://127.0.0.1:32333/v2/acl"
    body {
        username = "${username}"
        topic = "${topic}"
        action = "${action}"
    }
    headers {
        "Content-Type" = "application/json"
        "X-Request-Source" = "EMQX"
    }
}

We are using the Authentication HTTP Service and Authorization HTTP Service plugins of EMQ for forwarding these requests to Soteria and doing Authentication and Authorization. EMQ has caching mechanism, but it sends requests almost for each Publish message to Soteria. PS: On Subscribe we have only one message from client that need authorization and other messages are coming from server.

Architecture

arch

Support Vendors

Soteria supports having multiple vendors at the same time. Means you can use single cluster for multiple companies at the same time and validate their tokens and control accesses.

Vendor Configuration

company: "<<company_name>>"
driver_salt: ""
passenger_salt: ""
passenger_hash_length: 15
driver_hash_length: 15
allowed_access_types: ["pub", "sub"]
keys:
  iss-0: "key-value"
  iss-1: "key-value"
iss_entity_map:
  0: "entity-0"
  1: "entity-1"
  default: "default-entity"
iss_peer_map:
  0: "peer-0"
  1: "peer-1"
  default: "default-peer"
jwt:
  iss_name: "iss"
  sub_name: "sub"
  signing_method: "RS512"
topics:
  - topic1
  - topic2
  - ...

HashID Manager

driver_salt,passenger_salt, passenger_hash_length, driver_hash_length are used for HashIDManager. This component only works for passenger and driver issuers.

Keys

The following is a mapping that associates vendors (companies) with the keys used for opening JWT tokens. If symmetrical keys are utilized, it is important to use their base64 representation. It should also be noted that Soteria only requires public keys in cases where asymmetrical keys are employed.

IssEntityMap & IssPeerMap

These two configuration map iss to entity and peer respectively.

Note: default case is required

iss_entity_map:
  0: "driver"
  1: "passenger"
  default: "none"
iss_peer_map:
  0: "passenger"
  1: "driver"
  default: "none"

In the example above, we have two maps for entity & peer maps. As it's clear for entity structure 0 and 1 is mapped to driver and passenger, respectively. Vice Versa, for peer structure it can be seen that 1 and 0 is mapped to driver and passenger. We have also the default key for both two cases.

In the topic example, we have an accesses section in which 0 is mapped to 2 and 1 is mapped to -1 which can be interpreted as a map from IssEntity's Keys to Access Types. In the other words this structure means:

  • Driver has a Pub access on topic
  • Passenger has a None access on topic (No Access)

JWT

This is the JWT configuration. iss_name and sub_name are the name of issuer and subject in the JWT token's payload respectively.

signing_method is the method that is used to sign the JWT token. Here are list of different signing methods

  • ES384
  • RS512 *
  • PS512
  • RS384 *
  • HS256 *
  • HS384 *
  • RS256 *
  • PS384
  • ES256
  • ES512
  • EdDSA
  • HS512 *
  • PS256 Note: only the methods with * are supported for now.

Topic Configuration

type: "<<Name>>"
template: "<<regex template>>"
hash_type: 0|1
accesses:
  iss-0: "<<access>>"
  iss-1: "<<access>>"

Template

Topic template is a string consist of Variables and Functions and regular expressions.

Variables and Function are replaced first, and then the whole template will compile as a regular expression. The end result will be compared against the requested topic.

Example

This is template topic given in vendor:topics[#]:template.

- type: driver_location
  template: ^{{.company}}/driver/{{.sub}}/location$
  accesses:
    0: "2"
    1: "-1"
^{{.company}}/driver/{{HashID .hashType .sub (IssToSnappID .iss)}}/location/[a-zA-Z0-9-_]+$

After parsing the template we get something like this

// company=snapp
// hashType=0
// sub=D96ZbvJakLp4PYd
// iss=0
^snapp/driver/D96ZbvJakLp4PYd/location/[a-zA-Z0-9-_]+$

Now if the requested topic match the created topic it is considered as a valid topic for that particular user.

requested_topic: snapp/driver/D96ZbvJakLp4PYd/location/23fw49vxd
created_topic_regex: ^snapp/driver/D96ZbvJakLp4PYd/location/[a-zA-Z0-9-_]+$

Available Variables

These are the variables available to use in the topic templates.

  • iss issuer obtained from JWT token

  • sub subject obtained from JWT token

  • hashType Hash type field defined in topic template configuration

    HashType Value
    HashID 0
    MD5 1
  • company company field defined in vendor configuration

Available Functions

These are the function available to use in the topic templates.

  • IssToEntity(iss string) string convert iss obtained from JWT token to defined entity in issEntityMap
  • IssToPeer(iss string) string convert iss obtained from JWT token to define peer in issPeerMap
  • IssToSnappID(iss string) string convert iss obtained from JWT token to snappid.audience
  • HashID(hashType int, sub string, snappID snappid.audience) generated hashID for the given subject base on the hashType and snappid.audience

Note: snappid.audience only is available for issuer 0 and 1 which are for driver and passenger respectively.

Accesses

List of all types of access on a topic.

Access Value
Subscribe 1
Publish 2
Subscribe & Publish 3
None -1

Suggested Issuers

Use any value for issuer but if you have an entity called Driver or Passenger, we recommend use the following issuers for them.

Issuer Value
Driver 0
Passenger 1

soteria's People

Contributors

1995parham avatar amirhnajafiz avatar anvari1313 avatar davidcopperfield1991 avatar dependabot[bot] avatar mehditeymorian avatar moeen avatar mohammadiahmad avatar mostafa-fekri avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

soteria's Issues

Provide tests for auth/acl API

We have test cases for authenticators but we don't have any for APIs. APIs are internally uses authenticators but it would be great if we can cover them at least using simple hmac-based JWT token.

Support internal authentication

New release of EMQX (version 5) does not have a way for disabling authentication and authorization on a specific listener so we need to do the authentication and give the superuser access so we can actually reduce their future load on the system.

Because these are internal systems, we can use HMAC-based solutions for their JWT token and make the procedure easier than what we have for external services.

Support EMQX v5 authentication

In the new version of EMQX (v5), they support JSON request and response. We need to create new endpoints in which we can parse JSON
for getting username and password and then returning results as JSON. It is configurable in its user interface as follows:

image

In case of success, beside the status code,

HTTP/1.1 200 OK
Headers: Content-Type: application/json

you need to provide body as follows:

{
    "result": "allow", // options: "allow" | "deny" | "ignore"
    "is_superuser": true // options: true | fals, default value: false
}

https://www.emqx.io/docs/en/v5.2/access-control/authn/http.html#http-request-and-response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.