A scalable stateless Authorization Service for Federated Identities including Google and Facebook
- Documentation
- Introduction
- Features
- Tech Stack
- Quick Start
- Development Install
- Tech Specifications
- Usage
- Shoutouts
Explore documentation with the Ego Read the Docs.
Authorization Service built to provide Single Sign On for various microservices in an application. EGO works with Identity Providers such as Google, Facebook to provide social logins in the application. EGO provides stateless authorization using JWT (JSON Web Tokens) and can scale very well to a large number of users.
Interactive documentation of the API is provided using Swagger UI.
When run locally this can be found at: http://localhost:8081/swagger-ui.html
EGO Architecture
Here are some of the features of EGO:
- Single Sign on for microservices
- User-authentication through Federated Identities such as Google, Facebook, Github (Coming Soon), ORCID (Coming Soon)
- Uses JWT(Json Web Tokens) for Authorization Tokens
- Provides ability to create permission lists for users and/or groups on user-defined permission entities
- Built using well established Frameworks - Spring Boot, Spring Security
The application is written in JAVA using Spring Boot and Spring Security Frameworks.
- Spring Security
- JWT (JSON Web Tokens): This project uses jjwt library for JWT related features.
- OpenID Connect
The goal of this quick start is to get a working application quickly up and running. to start a dockerized version of EGO you can do the following:
1- Setup a google oauth client app in google cloud console
https://www.overture.bio/documentation/ego/installation/prereq/#google
use the following redirect URI: http://localhost:8081/oauth/code/google
2- Update docker-compose-all.yml
set the client id and secret:
# example on how to configure ego google oauth2 login
spring.security.oauth2.client.registration.google.clientId : ".."
spring.security.oauth2.client.registration.google.clientSecret: ".."
3- Run docker compose
docker-compose -f docker-compose-all.yml up
wait for all services to be up (ego ui takes few minutes)
4- EGO needs some seed data to authorize EGO UI as a client
you can refer to this make file for the exact command or if you have Make installed run: make init-db
docker exec ego_postgres_1 psql -h localhost -p 5432 -U postgres -d ego --command "INSERT INTO EGOAPPLICATION (name, clientId, clientSecret, redirectUri, description, status, errorredirecturi) VALUES ('ego ui', 'ego-ui', 'secret', 'http://localhost:8080/', '...', 'APPROVED', 'http://localhost:8080/error') on conflict do nothing"
5- you can access EGO ui (an admin dashboard) on http://localhost:8080/
and sign in with google
6- Ego swagger ui located at http://localhost:8080/swagger-ui.html
- Install Postgres
- Create a Database: ego with user postgres and empty password
- Run the migrations found here: SQL Script to setup tables.
Database migrations and versioning is managed by flyway.
- Download the flyway cli client here: flyway-commandline
- Unpack the client in a directory of your choosing
- Execute the flyway client pointing it to the configuration and migration directories in this repository.
Get current version information:
./fly
Run outstanding migrations:
./fly migrate
To see the migration naming convention, click here.
- EGO currently supports three Profiles:
- default: Use this to run the most simple setup. This lets you test various API endpoints without a valid JWT in authorization header.
- auth: Run this to include validations for JWT.
- secure: Run this profile to enable https
- Run using Maven. Maven can be used to prepare a runnable jar file, as well as the uber-jar for deployment:
$ mvn clean package
To run from command line with maven:
$ mvn spring-boot:run
ego JWT will have a similar format as the one described in RFC: kf-auth-rfc An example ego JWT is mentioned below:
{
"alg": "HS512"
}
.
{
"sub": "1234567",
"iss": "ego:56fc3842ccf2c1c7ec5c5d14",
"iat": 1459458458,
"exp": 1459487258,
"jti": "56fd919accf2c1c7ec5c5d16",
"aud": [
"service1-id",
"service2-id",
"service3-id"
],
"context": {
"user": {
"name": "Demo.User@example.com",
"email": "Demo.User@example.com",
"status": "Approved",
"firstName": "Demo",
"lastName": "User",
"createdAt": "2017-11-23 10:24:41",
"lastLogin": "2017-11-23 11:23:58",
"preferredLanguage": null,
"roles": ["ADMIN"],
"groups": ["GroupOne", "GroupTwo"],
"permissions": ["Study001.WRITE", "Study002.DENY"]
}
}
}
.
[signature]
- "aud" field can contain one or more client IDs. This field indicates the client services that are authorized to use this JWT.
- "groups" will differ based on the domain of client services - each domain of service should get list of groups from that domain's ego service.
- "permissions" will differ based on domain of client service - each domain of service should get list of permissions from that domain's ego service.
- Unit Tests using testcontainers will also run flyway migrations to ensure database has the correct structure
Applications can be added to EGO with a client ID/Secret pair. The ID and Secret can be used to authenticate with EGO to retrieve a JWT.
An application JWT will not have roles
but will list the groups
the application is associated with. Other applications are responsible for controlling authorization for applications based on the content of their signed JWT.
To register an application with EGO make a request as documented at /swagger-ui.html#!/application-controller/createUsingPOST
This request must have an ADMIN
role JWT in the Authorization field.
Keep the client ID/Secret pair in a secret place, for use by the application only. Do not make these values visible in the browser or in your code base.
Authentication uses the oauth client_credentials flow. This can be handled out-of-the-box by many REST clients (ex. Insomnia).
The Authenticate request details, to recreate manually:
POST
request tohttps://{{ego-domain}}/oauth/token
- Body content, content-type:
x-www-form-urlencoded
grant_type:client_credentials
client_id:{{application's client id}}
client_secret:{{application's client secret}}
curl example:
http://localhost:8081/oauth/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials&client_id=my-app-id&client_secret=secretpassword'
Many thanks to Browserstack for giving our test capabilities a powerup!