Skip to content

Latest commit

 

History

History
252 lines (212 loc) · 13.5 KB

File metadata and controls

252 lines (212 loc) · 13.5 KB

Authorization / Authentication microservice

Why

  • Get an opportunity to restrict users, so that they can't send requests to microservices without required credentials and permissions.
  • Provide for developers the solution for cases when OpenMatchmaking should work with the dedicated authorization/authentication server, withot communicating with existing authorization/authentication servers.
  • Necessary to store an information about users and let them to get (or refresh) an access token.
  • Required a storage for microservices permissions, so that they can be assigned to each existing user

Benefits of using

  • Can be used as the 3rd party authorization/authentication service for restricting an access in a pair with reverse proxy
  • A good choice for cases when Open Matchmaking project should work independently, without communicating with other services (not related to Open Matchmaking)

General information

General principles of auth/auth microservice can be shown with the following picture:

As you can see on the picture, the microservice is communicating with two different entities:

  1. With reverse proxy, which is sending requests to the certain microservice (in this case they are to Auth/Auth microservice) with a content inside.
  2. With internal parts of Open Matchmaking which are communicating via specially created message queues for auth/auth microservice. It's a hidden part, a don't provide any public APIs for endusers. Only for internal usage.

Entity relationship diagram

IMPORTANT: The tables "Group", "Permission" and "Microservice" will be updated by the other part of microservice, that will be handling requests from inner microservices after their instantiating.

User table

Field name Field type Constraints Description
id UUID PK A database unique object identifier
username VARCHAR UNIQUE, NOT NULL A unique username
password VARCHAR NOT NULL User password hash
group Relation Many-To-Many Relationship to Group

Group table

Field name Field type Constraints Description
id UUID PK A database unique object identifier
name VARCHAR NOT NULL A permission group name
permissions Relation Many-To-Many Relationship to Permission

NOTE: On the first start of this microservice, the Group table should contain the following groups without permissions if they aren't created yet: "Game client".

Permission table

Field name Field type Constraints Description
id UUID PK A database unique object identifier
codename VARCHAR NOT NULL A permission name in "{microservice}.{resource}.{action}" format
description VARCHAR Human-readable description about the permission

Microservice table

Field name Field type Constraints Description
id UUID PK A database unique object identifier
name VARCHAR UNIQUE, NOT NULL A unique Microservice identifier
version VARCHAR NOT NULL Microservice version in "{major}.{minor}.{patch}" format
permissions Relation One-To-Many Relationship to Permission

API Endpoints

Method Endpoint Usage Returns
GET /auth/api/health-check Health check endpoint for API Gateways "OK"

RabbitMQ exchanges and queues

Exchanges

Exchange name Exchange type Options
open-matchmaking.auth.token.new.direct direct durable=True, passive=False, auto_delete=False
open-matchmaking.auth.token.verify.direct direct durable=True, passive=False, auto_delete=False
open-matchmaking.auth.token.refresh.direct direct durable=True, passive=False, auto_delete=False
open-matchmaking.auth.users.retrieve.direct direct durable=True, passive=False, auto_delete=False
open-matchmaking.auth.users.register.direct direct durable=True, passive=False, auto_delete=False

Queues

Queue name Queue options Exchange name Usage Returns
auth.microservices.register durable=True, passive=False, exclusive=False, auto_delete=False open-matchmaking.direct Register a new microservice with permissions "OK" or a validation error
auth.token.new durable=True, passive=False, exclusive=False, auto_delete=False open-matchmaking.auth.token.new.direct Get an access token (or an access token and refresh token) A new JSON Web Token or a validation error
auth.token.verify durable=True, passive=False, exclusive=False, auto_delete=False open-matchmaking.auth.token.verify.direct Returns with whether or not a given access token is valid {"is_valid": true} or a validation error
auth.token.refresh durable=True, passive=False, exclusive=False, auto_delete=False open-matchmaking.auth.token.refresh.direct Validates the refresh token, and provides back a new access token A new JSON Web Token
auth.users.retrieve durable=True, passive=False, exclusive=False, auto_delete=False open-matchmaking.auth.users.retrieve.direct Returns an information about the current user User
auth.users.register durable=True, passive=False, exclusive=False, auto_delete=False open-matchmaking.auth.users.register.direct Create a new user for the game client User or a validation error

Request and response examples

Registering microservice

For registering a microservice a developer should send a message to the auth.microservices.register queue with content inside in JSON format and content_type=application/json in headers. The content must contain the following fields:

Field name Parent Description Type
name Stores the name of the microservice. String
version Specifies the version of the registered microservice. Must specified in the major.minor.minor format. String
permissions Specifies a list of available permissions. List of objects
codename permissions[index].object Defines the permissions name. Must specified in the microservice.resource.action format. String
description permissions[index].object A short description of the certain permissions. String

An example of a request for registering:

{
    'name': 'my-microservice',
    'version': '0.1.0',
    'permissions': [
        {
            'codename': 'my-microservice.stats.retrieve',
            'description': 'Can retrieve the player statistics'
        },
        {
            'codename': 'my-microservice.stats.update',
            'description': 'Can update the player statistics'
        }
    ]
}

Creating a new JSON Web Token (JWT)

For creating a new JSON Web Token the user needs to send a message to the auth.token.new queue with a content that contains the following fields:

Field name Parent Description Type
username A user's login. String
password A password from the account. String

An example of the request from the reverse proxy:

{
    'username': 'some_user',
    'password': 'super_secret_password'
}

An example of the response:

{
  'content': {
     'access_token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhdXRoIiwiaWF0IjoxNTM4NTcwMTk0LCJleHAiOjE1NzAxMDYxOTUsImF1ZCI6IiIsInN1YiI6IiJ9.Z3zURZaWvX1p2B5dRqO1ma1-NC6Ip7blYIEyzylSi4s',
    'refresh_token': 'd49ac89a2da505b689281f70460d80e0'
  },
  'event-name': 'generate-new-token'
}

Each access_token contains a user_id in payload so that the any server could understand which user is doing the certain action under the resource.

Verifying the JSON Web Token (JWT)

For verifying the generated JSON Web Token the user needs to send a message to the auth.token.verify queue with a content that contains the following fields:

Field name Parent Description Type
access_token A generated JSON Web Token. String

An example of the request from the reverse proxy:

{
    'access_token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhdXRoIiwiaWF0IjoxNTM4NTcwMTk0LCJleHAiOjE1NzAxMDYxOTUsImF1ZCI6IiIsInN1YiI6IiJ9.Z3zURZaWvX1p2B5dRqO1ma1-NC6Ip7blYIEyzylSi4s'
}

An example of the response:

{
  'content': {
    'is_valid': true
  },
  'event-name': 'verify-jwt'
}

Refreshing the JSON Web Token (JWT)

For refreshing the JSON Web Token the user needs to send a message to the auth.token.refresh queue with a content that contains the following fields:

Field name Parent Description Type
access_token A generated JSON Web Token. String
refresh_token A generated JSON Web Token which using for generating a new access JSON Web Token. String

An example of the request from the reverse proxy:

{
    'access_token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhdXRoIiwiaWF0IjoxNTM4NTcwMTk0LCJleHAiOjE1NzAxMDYxOTUsImF1ZCI6IiIsInN1YiI6IiJ9.Z3zURZaWvX1p2B5dRqO1ma1-NC6Ip7blYIEyzylSi4s',
    'refresh_token': 'd49ac89a2da505b689281f70460d80e0'
}

An example of the response:

{
  'content': {
    'access_token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhdXRoIiwiaWF0IjoxNTM4NTcyMDI2LCJleHAiOjE1NzAxMDgwMjYsImF1ZCI6IiIsInN1YiI6IiJ9.UmRDMP6ocNacTD7clmCWwtO74PvFRwgjnvvf6k-bYY0'
  },
  'event-name': 'refresh-jwt'
}

Retrieving a user profile

For verifying the generated JSON Web Token the user needs to send a message to the auth.users.retrieve queue with a content that contains the following fields:

Field name Parent Description Type
access_token A generated JSON Web Token. String

P.S. In actual moment of time users can retrieve only his own user profile that associated with the generated token by Auth/Auth microservice.

An example of the request from the reverse proxy:

{
    'access_token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIiLCJpYXQiOjE1Mzk2NzY2NDYsImV4cCI6MTU3MTIxMjY0NywiYXVkIjoiIiwic3ViIjoiIiwidXNlcl9pZCI6IjViYjRjOTg0MWY4ZWMwMDA0NTI0YTU0ZiJ9.3jUYf-ffQVJjdERnSYXApTAfvA3QLsiIQIWDQKHniZE'
}

An example of the response:

{
  'content': {
    'id': '5bb4c9841f8ec0004524a54f',
    'username': 'some_user',
    'permissions': ['matchmaking.games.retrieve', 'matchmaking.games.update']
  },
  'event-name': 'get-profile'
}

Registering a new user

For verifying the generated JSON Web Token the user needs to send a message to the auth.users.register queue with a content that contains the following fields:

Field name Parent Description Type
user A unique username. String
password A password for the account. String
confirm_password A password confirmation. String

An example of the request from the reverse proxy:

{
    'username': 'some_user',
    'password': '123456',
    'confirm_password': '123456'
}

An example of the response:

{
  'content': {
    'id': '5bb4c9841f8ec0004524a54f',
    'username': 'some_user'
  },
  'event-name': 'new-game-client'
}