Skip to content

Real-world example of how to implement OAuth 2.0 protocol authentication flows in a Command Line Interface (CLI) using oclif and Keycloak! πŸš€

License

Notifications You must be signed in to change notification settings

wnqueiroz/oclif-keycloak-oauth2-flows-sample

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

13 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

oclif-keycloak-oauth2-flows-sample

Real-world example of how to implement OAuth 2.0 protocol authentication flows in a Command Line Interface (CLI) using oclif.io and Keycloak! πŸš€

oclif demo.gif

Summary

Motivation ✨

CLI authentication can even be trivial when you use -u for username and -p for password to perform authentication. This real-world example originated from the idea of figuring out how CLIs like GitHub and Heroku perform login using more elegant flows than just inputting username and password. Using Keycloak in the use case was just to avoid having to create an OAuth Server from scratch πŸ˜….

The purpose and resolution of this project was to answer questions such as:

  • How to login a user in a CLI without explicitly using credentials (with the -u and -p flags, for example);
  • Is it possible to use the OAuth 2.0 protocol in a command line interface?
  • How and where to store user credentials while maintaining an active session from a command-line interface?

The answer to these (and maybe even other questions) you can find in the source code and README.md of this project.

Before exploring

As I mentioned above, using Keycloak was just for him to take care of our OAuth Server part. As it is a dependency for the project to work well, you need to provision a Keycloak instance in your environment. Let's do this using Docker with docker-compose.

Pre-requisites

In this walkthrough it's assumed that you have the tools installed:

Up and Running!

There is already a docker-compose.yaml configured in this project. In the terminal, in the root of the project, execute the command to start the Keycloak:

docker-compose up -d

Let's check the logs if Keycloak has started:

docker-compose logs -f keycloak | grep -i "Admin console listening on"

πŸ’‘ Wait until a message appears on terminal output. After viewing the log, Keycloak will be available at: http://127.0.0.1:8080

Thanks to the .docker/keycloak-realm.json file we won't need to waste so much time in this configuration. The only thing you will need to do is register a new account when running the CLI authentication command (clicking the register button and setting the basic information and credentials).

The Command Line OAuth 2.0 Tricks

There are some tricks to perform transparent user authentication (avoiding the need for credentials to be copied back and forth).

Diagrams

Device Code Flow

sequenceDiagram
    autonumber
    title: Device Code Flow

    actor User
    participant CLI
    participant OAuth Server

    User->>CLI: ./bin/dev auth login -f device-code
    CLI->>OAuth Server: Request device code
    note right of CLI: POST /auth/token
    OAuth Server->>CLI: Returns device_code, user_code, <br> verification_uri, and interval
    CLI->>User:  Open browser with verification_uri <br> (Waiting for authentication...)
    CLI->>+OAuth Server: Poll for access_token and refresh_token
    note right of CLI: POST token
    par browser
        User->>OAuth Server: Enter user_code
        note right of OAuth Server: Mark device as authorized
    end
    OAuth Server->>-CLI: Returns access_token and refresh_token
    CLI->>CLI: Save user credentials in $HOME/.clirc file
    CLI->>User: Waiting for authentication... done βœ…
Loading

Authorization Code Flow

sequenceDiagram
    autonumber
    title: Authorization Code Flow (with PKCE)

    actor User
    participant CLI
    participant OAuth Server

    User->>CLI: ./bin/dev auth login -f authorization-code
    CLI->>CLI: Generate the PKCE Challenge <br> (code_challenge, code_verifier and state)
    note right of CLI: Store state to user later
    CLI->>CLI: Build authorization code URL
    CLI->>CLI: Start local server (http://127.0.0.1:5657)
    CLI->>User:  Open browser with authorization code URL <br> (Waiting for authentication...)
    par browser
        User->>OAuth Server: Enter with user credentials
    end
    OAuth Server->>CLI: Redirects to <br> http://127.0.0.1:5657/auth/callback <br> with parameters (code, state)
    CLI->>CLI: Validates that it is not a possible CRSF attack
    note right of CLI: Compares the received state with the previous one
    CLI->>OAuth Server: Request access_token and refresh_token
    note right of CLI: POST /token
    OAuth Server->>CLI: Returns access_token and refresh_token
    CLI->>CLI: Save user credentials in $HOME/.clirc file
    CLI->>User: Waiting for authentication... done βœ…
Loading

Commands

./bin/run auth login

Authenticate with Keycloak

USAGE
  $ ./bin/run auth login [-f device-code|authorization-code]

FLAGS
  -f, --flow=<option>  Authentication flow
                       <options: device-code|authorization-code>

DESCRIPTION
  Authenticate with Keycloak

./bin/run auth logout

Log out of Keycloak

USAGE
  $ ./bin/run auth logout

DESCRIPTION
  Log out of Keycloak

./bin/run auth status

View authentication status

USAGE
  $ ./bin/run auth status

DESCRIPTION
  View authentication status

./bin/run help [COMMAND]

Display help for ./bin/run.

USAGE
  $ ./bin/run help [COMMAND] [-n]

ARGUMENTS
  COMMAND  Command to show help for.

FLAGS
  -n, --nested-commands  Include all nested commands in the output.

DESCRIPTION
  Display help for ./bin/run.

See code: @oclif/plugin-help

About

Real-world example of how to implement OAuth 2.0 protocol authentication flows in a Command Line Interface (CLI) using oclif and Keycloak! πŸš€

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published