hapi-openid-connect
v4.0.1
Published
A Hapi plugin implementation of the core and discovery OpenID-Connect provider API
Downloads
101
Readme
hapi-openid-connect
This module is a Hapi plugin implementation of the core and discovery OpenID-Connect / OAuth 2.0 provider API.
Please Note That This Plugin Is An Implementation Of The More Recent (Newer) Version Of OpenID: OpenId Connect, And It Does Not Support The Older OpenID 2.0. All OpenID 2.0-specific features, such as realm, are not supported. Furthermore, there is no plan for this plugin to support migration from the older OpenID 2.0 to the newer OpenID Connect.
Release (>= 3.x.x) of this plugin is upgraded for hapi version >= 17,. It is compliant with the OpenID Connect / OAuth 2.0 documentation, and offers the following endpoint implementation:
1- authorization endpoint:
2- The discovery implementation of OpenID Connect is implemented. The specification implementation is comprised in the following endpoints:
- JWKS endpoint: for retrieval of public key
- JWKS_X5C endpoint: for retrieval of public X5C certificate
- /.well-known/openid-configuration endpoint: for a JSON documentation of the entire discovery API implementation.
3- The token endpoint implementation covers:
- Authorization Code Grant Type
- Resource Owner Password Credentials Grant Type
4- The user_info endpoint:
- The signin (login) function is implemented to fully support redirects as per the OpenID Connect specification for the Authorization Code Request. The implementation requires/depends on the hapi-auth-cookie plugin.
- The signout function is implemented
Limitations of The Current Release
- Client dynamic registration IS NOT INCLUDED", it is left to the plugin user to implement
- Only authorization code flow request is implemented
- The token endpoint DOES NOT IMPLEMENT the Refresh Token Grant Type
Usage
Sample Application
This release includes a fully functional sample application (sample_app), built on the valde-hapi stack. The sample application:
1- is intended as a guidance implementation, and it is not a full implementation of OP.
2- uses mongoDB for persistence of authorization requests, and tokens.
3- relies on an instance of nginx for termination of the SSL
4- relies on mongoDB indexes ("expireAfter" indexes) for automatic deletion of expired tokens.
5- provides guidance on the implementation of the registrars required for the hapi-openid-connect plugin.
Configuration
The hapi-openid-connect plugin is a standard hapi plugin, and is registered on the hapi stack in a standard way:
let hapi_openid_connect = require("hapi-openid-connect");
...
server.register(hapi_openid_connect, oidc_options, callback);
...
Where oidc_options is a json configuration object as follows:
{
"oidc_url_path": "/sample_app/oidc",
"version": 1,
"configuration": {
"issuer": "https://localhost:8443/sample_app/oidc",
"issuer_audience": "123456788",
"scopes_supported": [
"profile",
"address",
"email",
"phone"
],
"jwk": {
"cert_type_rsa": true,
"priv_key_file_name": "./config/oidc/sampleapp-key.pem",
"pub_key_file_name": "./config/oidc/sampleapp-cert.pem",
"cert_chain_file_name": "./config/oidc/sampleapp-cert-chain.pem"
},
"authorization_endpoint": {
"authorization_request_registrar_module": "/lib/authorization_request_registrar_module"
},
"token_endpoint": {
"token_registrar_module": "/lib/token_registrar_module",
"authorization_code_grant_type": {
"token_duration_seconds": 600
},
"password_grant_type": {
"token_duration_seconds": 900
}
},
"user_info_endpoint": {
"user_authentication_url": "https://localhost.sampleapp.com:8443/sample_app/oidc/signin",
"user_post_login_account_url": "https://localhost.sampleapp.com:8443/sample_app/oidc/account",
"user_account_registrar_module": "/lib/user_account_registrar_module"
},
"client_endpoint": {
"client_registrar_module": "/lib/client_registrar_module"
}
}
}
Configuration Attributes
Most of the attributes in the json configuration object are self-explanatory, and the registrar ones are described as follows:
authorization_endpoint
authorization_request_registrar_module: This attribute is a path to a commonjs module which will be "required" by the hapi-openid-connect code. The hapi-openid-connect plugin require this module to export the following functions, which must return promises:
1- put_authorization_request(authorization_request) which must update the authorization_request object in the persistence store.
2- get_authorization_request(authorization_request_id) which must retrieve the authorization_request associated with the authorization_request_id argument from the persistence store.
3- post_authorization_request(authorization_request) which must persist the authorization_request object, and return an id for it.
4- delete_authorization_request(authorization_request_id) which must delete the authorization request from the persistence store
token_endpoint
token_registrar_module: This attribute is a path to a commonjs module which will be "required" by the hapi-openid-connect code. The hapi-openid-connect plugin require this module to export the following functions, which must return promises:
1- put_token(oidc_token) which must update the oidc_token object in the psersistence store.
2- get_token(oidc_token_id) which must retrieve the oidc_token associated with the oidc_token_id argument from the persistence store. The oidc_token_id is also used as the access_token.
3- post_token(oidc_token) which must persist the oidc_token object, and return an id for it.
4- delete_token(oidc_token_id) which must delete the oidc_token request from the persistence store.
usrer_info_endpoint
user_authentication_url: this is the https URL for the end_user authentication page (signin or login page).
user_post_login_account_url: this is the https URL for the end_user account page (after signin or login page).
user_account_registrar_module: This attribute is a path to a commonjs module which will be "required" by the hapi-openid-connect code. The hapi-openid-connect plugin require this module to export the following functions, which must return promises:
get_user_account_id_for_credentials(username, password):
- verify that the username and password match a user account record
- if the user account is found, set the hapi-auth-cookie session cookie for the request if not already set.
- return a Promise that must resolve with the user account id (the id is a unique string for the respective user account)
- reject the Promise if the user account does not exist, or the credentials provided do not match.
The returned/resolved user account id must be a string, and it must be less than 255 characters (as per the OpenID specs).
client_endpoint
client_registrar_module: This attribute is a path to a commonjs module which will be "required" by the hapi-openid-connect code. The hapi-openid-connect plugin require this module to export the following functions, which must return promises:
get_client_registration(clientId): This method must return a Promise which resolves to the client registration entry from a persistent store. The client registration entry must at least have the following attributes:
- redirect_uri_hostname
- redirect_uri_port
- redirect_uri_path, and
- description, which describes the permissions the client is requesting.
get_client_account_id_for_credentials(username, password):
- verify that the username and password match a client account record
- return a Promise that must resolve with the client account id (the id is a unique string for the respective client account)
- reject the Promise if the client account does not exist, or the credentials provided do not match.
The returned/resolved user account id must be a string, and it must be less than 255 characters (as per the OpenID specs).
process_signin_request(request, h):
- verify that the username and password match a client account record
- setup the session state to reflect signed in state if an account is found for the credentials in request.payload.username and request.payload.password
- return a Promise that must resolve with the client account id (the id is a unique string for the respective client account)
- reject the Promise if the client account does not exist, or the credentials provided in request.payload do not match.
The returned/resolved user account id must be a string, and it must be less than 255 characters (as per the OpenID specs).