Skip to content

OAuth2 Authorization Server implemented on top of a IBM Domino Server

Notifications You must be signed in to change notification settings

lhervier/oauth2-dom-auth-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

Table of Contents

The goal of this project is to transform a standard IBM Domino v9.0.1 server into an OAUTH2 authorization server (also know as an OAUTH2 provider), with OpenID extensions. Your server will generate access tokens that client applications will be able to use to access protected resources. Resource servers will be able to validate the token using a standard token introspection endpoint.

Please, note that nor the client applications, nor the protected resources have to be hosted on a Domino Server !

Pre-installation step: Declaring the SSO Configurations

I didn't want to take the risk of storing keys myself. Instead, I prefered using SSO Configurations which are natively stored by IBM in a secure manner.

So, when Domino will generate OAUTH2 access tokens, it will use secrets stored in SSO configuration documents.

You will have to generate three of them :

  • One key that will be used to sign the access token.
  • Another one to sign the OpenID token.
  • And a last one to encrypt the refresh token.

To create the three needed SSO Configurations, open your names.nsf, go to the "Servers" view, and use the "Web/Create Web SSO Configuration" action :

  • Name your configuration: For example "AccessToken", "IdToken", and "RefreshToken"
  • Enter the name of your organisation: We will use "ACME" in this example.
  • DNS Domain: ".acme.com". This information is mandatory, but will not be used.
  • Domino Server Names: Enter the name of the servers that will act as OAUTH2 authorization servers.

Deploy on production environment

Deploy the dom-spring plugins on your Domino Server

The dom-spring plugins must be deployed into your Domino Server. Documentation on how to deploy the plugins is available in the README file of the project on git hub :

https://github.com/lhervier/dom-spring

Deploy the oauth2-dom-auth-server plugins on your Domino Server

The procedure is almost the same as for the dom-spring plugins.

First, download the latest update site from the github release page, and unzip it where you want.

Then, create a new database named "Oauth2UpdateSite.nsf" (you can name it the way you want) on your server, using the "Eclipse Update Site" advanced template.

Open the database with your Notes client, and click on the "Import local update site" button. Go select the "site.xml" in the unzipped version of the update site.

Add (or update) the notes.ini variable "OSGI_HTTP_DYNAMIC_BUNDLES". It must point to your "Oauth2UpdateSite.nsf" database. Use a comma to separate multiple values if you already have another entry (for dom-spring for example).

Restart the http task (console command):

restart task http

Check that plugins are deployed :

tell http osgi ss oauth

You should see something like this :

> tell http osgi ss oauth
[1C04:0002-1C08] 28/09/2017 14:27:39   Framework is launched.
[1C04:0002-1C08] 28/09/2017 14:27:39   id       State       Bundle
[1C04:0002-1C08] 28/09/2017 14:27:39   95       <<LAZY>>    com.github.lhervier.domino.oauth.server_1.0.0.qualifier
[1C04:0002-1C08] 28/09/2017 14:27:39   96       RESOLVED    com.github.lhervier.domino.oauth.external.commons_io_2.5.0
[1C04:0002-1C08] 28/09/2017 14:27:39   99       RESOLVED    com.github.lhervier.domino.oauth.external.nimbus_jose_jwt_4.37.1

The oauth2.nsf database

This database will store the definition of the authorized OAUTH2 client applications. It will also store the authorization codes. Because of this, it is a sensible database, and you will have to be strict with its ACL.

Create the database

You can download the "oauth2.nsf" database from the release page of github. Just copy it to your Domino server, and don't forget to sign it. Note that beacuse it contains a XPage, it must be signed with an id allowed to run unrestricted agents.

Check the ACL

Users with the [AppManager] role will be allowed to register/edit/remove oauth2 client applications. Users with this role MUST also be able to add users in the Domino Directory (we will generate users on the fly)

Users with the [AuthCodeManager] role will be able to access all the generated authorization code documents. These are sensible data, protected with a reader field. Nobody should have this role. It is present for development purpose, and can be replaced by the "Full access Administrator" option of Domino Administrator.

Every other users that should be able to log into one of the OAUTH2 client application should have reader access.

So, by default, the ACL is :

  • Anonymous "no access"
  • "LocalDomainAdmins" as manager with [AppManager] and [AuthCodemanager] roles.
  • Default "reader" to allow every regular Domino users to log in via OAuth2.

Configure the oauth2 server environment

This project uses the Domino Spring project. As such, it is using properties that are readed by the Spring Framework. The code doesn't care about where they come from. And Spring is able to access properties from about anywhere.

To make our database work, we will have to declare a set of properties. But we can declare them in multiple places :

  • From environment variables
  • From notes.ini variables
  • Or we can inject them ourself by writing a simple osgi plugin that extends the domino spring plugin (and store those properties in an external database for example).

I will show you how to declare them with any of those methods. But first, let's describe the properties and their awaited values :

Property Description Example value
oauth2.server.db Path to the oauth2 database. Needed to prevent the endpoint to be made available on ALL databases of the server. oauth2.nsf
oauth2.server.nab Path to a std Domino Directory in which we will generate the users associated with the registered client apps. names.nsf
oauth2.server.applicationRoot When we will create a user for an application, we will name it using the application name and this prefix. /O=APPLICATION
oauth2.server.refreshTokenConfig Name of the SSO configuration that contains the secret we will use to encrypt the refresh tokens. ACME:RefreshToken
oauth2.server.refreshTokenLifetime Lifetime in seconds of the generated refresh tokens. Should be a long value (10h). 36000
oauth2.server.authCodeLifetime Max time ellapsed (in seconds) between user login and the server asking for the access token. 60
oauth2.server.core.signKey Name of the SSO configuration that contains the secret we will use to sign the access tokens. ACME:AccessToken
oauth2.server.core.iss Issuer of the access token (iss property of the JWT). https://acme.com/domino/oauth2/
oauth2.server.core.expiresIn Lifetime in seconds of the generated access tokens. 1800
oauth2.server.openid.signKey Name of the SSO configuration that contains the secret we will use to sign the openid id tokens. ACME:IdToken
oauth2.server.openid.iss Issuer of the openid id token (iss property of the JWT). https://acme.com/domino/oauth2/openid/
oauth2.server.openid.expiresIn Lifetime in seconds of the generated id tokens. 36000

Whatever the method you use to define those properties, when done, restart the http task.

Declare properties as notes.ini variables

Eveything is in the title. Just edit your notes.ini file, and add variables named the same way as the properties.

You can also declare the variables in a configuration document.

Inject properties from an osgi plugin

Read the documentation of the Domino Spring project, or contact me (create an issue) if you want more details.

This method allows you to inject values from the place you want. And of course, most of my clients wants to extract parameters from a common NSF.

Registering an OAuth2 client applications

Use your browser to access the following url :

http://<your server>/oauth2.nsf

You will have to login with a user with the [AppManager] role.

Registering an application will add a user in the nab. The application secret is its http password. Don't forget to save this value. We won't be able to extract it again.

The OAuth2 and OpenID endpoints

Authorize endpoint : http://server/oauth2.nsf/oauth2-server/authorize

Token endpoint : http://server/oauth2.nsf/oauth2-server/token

RFC7662 Access Token Introspection End point : http://server/oauth2.nsf/oauth2-server/checkToken

OpenID UserInfo end point : http://server/oauth2-server/userInfo (note that there is NO reference to oauth2.nsf !!!)

Supported OAuth2 flows

Authorization Code, Implicit and OpenID Hybrid flows are supported.

Client Credentials, and User credentials flows are NOT supported.

Supported scopes

All OpenID scopes are supported : openid, profile, email, address, etc...

Generate the update site yourself (from sources)

Download the source

First, clone or download the source code from github into a local folder.

Download the dom-spring update site (or generate it yourself)

Refer to the dom-spring project page to donwload it.

Using Domino Designer

Install the dom-spring update site

  • Go to File/Preferences menu, in the "Domino Designer" section, and check "Enable Eclipse plug-in install"
  • Now, go to File/Application/Install menu.
  • Select "Search for new features"
  • Add a "Zip/jar location" and go find the zip that correspond to the dom-spring update site.
  • Click Finish, and accept licences.
  • Designer will ask to restart.

Import the source code

  • Open Domino Designer
  • Open the "package explorer" view, right click in the blank part, and select Import.
  • In the "General" section, select "Existing projets into workspace"
  • Click "Browse" and select the folder named "domino-osgi" in this project's sources.
  • Select all projects and click "Import"

The code is now imported in your IBM Domino Designer. It should compile fine.

Generate the update site

Open the file named site.xml in the "domino-osgi/com.github.lhervier.domino.oauth.update" project, and click the "Build all" button.

Using Eclipse Oxygen

Install the XPages SDK

Download the XPages SDK zip file from :

https://www.openntf.org/main.nsf/project.xsp?r=project/XPages%20SDK%20for%20Eclipse%20RCP

Unzip the file to the folder of your choice. Then, in Eclipse, go to the menu "Help / Install new software".

In the dialog box, click the "add" button in from of the "Work with" combo :

  • Name = XPages sdk
  • Click the "Folder" button, and go find the folder named "org.openntf.xsp.sdk.updatesite" in the extracted zip file.

Select all features, accept licences, "Install anyway" when prompted to, and restart Eclipse.

Declare Java Runtime and Target Platform

Open Eclipse preferences, and go to the section "XPages SDK" :

  • Enable using IBM DOMINO on this computer
  • Enter the path to the notes.ini, the installation folder of your Domino Server, and the path to your data folder.
  • Click "Automatically create JRE for domino"
  • And "Apply".

This will create a new JRE Runtime, and a new Target platform. Select them :

  • Go to the section "Java / Installed JREs", and select the newly created JRE (XPages Domino JRE)
  • Go to the section "Plugins Development / Target platform", and select the newly created target platform (Domino Target).

Install the dom-spring plugins

  • Menu Help / Install New Software
  • Add an update site
  • Go find the update site (the zip file) you juste downloaded
  • Click next, finish, etc... until Eclipse ask to reboot.

Import the sources

In the package explorer, right click :

  • Select "Import", then choose "General / Existing project into workspace".
  • Go search for the folder where you cloned the sources
  • And import the projects.

The code should compile fine.

Generate the update site

Once the code is deployed, you will be able to generate the update site by opening the site.xml file of the "com.github.lhervier.domino.oauth.update" project. Simply click the "Build all" button.

Using maven

As the dom-spring plugins are not available at maven central, you must first install them manually. For this, follow the README.md file present in the dom-spring github website :

  • Install "IBM Domino Update Site for Build Management", let's say in c:\UpdateSite
  • Download dom-spring source code
  • In the source folder run the maven install command : mvn install -Dnotes-platform=file:///c:/UpdateSite

Now that your local maven repository is initialized, generate the oauth2-dom-auth-server update site. CD into the "domino-osgi" folder, and just type :

mvn install -Dnotes-platform=file:///c:/UpdateSite

The update site will be generated in

/domino-osgi/com.github.lhervier.domino.oauth.update/target/com.github.lhervier.domino.oauth.server.update-<version>.zip

Generate the oauth2.nsf database yourself (from source)

Instead of copying it from github, in Domino Designer (you cannot use Eclipse here !), import the project named "oauth2-ondisk".

Then, create a new NSF on the server using the standard Domino Designer tool (right click/Team Development/etc...)

Using the Rest API

A rest API is provided. For the moment, it does not work with a bearer token :) You will have to send the username and the password of an authorized user (ie, a user with the [AppsManager] role, in the "Authorization Basic" header :

Authorization: Basic <username:password encoded in base 64>

You will then have the following APIs :

List all the declared applications :

GET /api/applications : 

Sample return value :

[
	{name:"app1", clientId:"azerty"},
	{name:"app2", clientId:"qsdfgh"}
]

Get the details of a given application

GET /api/applications/<client id>

Sample return value :

{
	"name": "app1",
	"clientId: "azerty",
	"redirectUri": "http://acme.com",
	"redirectUris": ["http://acme.com/login", "http://acme.com/init"]
	"readers": "*"
}

Create a new application

POST /api/applications
{
	"name": "app1",
	"redirectUri": "http://acme.com",
	"redirectUris": ["http://acme.com/login", "http://acme.com/init"]
	"readers": "*"
}

Sample return value :

{
	"clientId": "azerty",
	"secret": "a generated super secret password"
}

Update an existing application

POST /api/applications/<client id>/put
{
	"redirectUri": "http://acme.com",
	"redirectUris": ["http://acme.com/login", "http://acme.com/init"]
	"readers": "*"
}

You cannot change nor the name, nor the client id with this API. Note that we are not using a PUT request because the Domino Servers don't allow such requests by default (and I don't want to add a mandatory configuration update)

Remove an application

GET /api/applications/<client id>/delete

Again, the API is using a GET request instead of a DELETE request because DELETE request are forbidden at the server level by default.

Ask the local domino Server to load plugin code from the workspace

If you want to play with the code, you will have to make your local Domino Server aware of the plugins compiled by your IDE.

If you already have imported the dom-spring plugins, you should have already installed the IBM Domino Debug Plugin in Eclipse or Domino Designer, and declared a debug configuration.

Simply go editing this debug configuration, and select the new plugins that corresponds to oauth2-dom-auth-server.

Click run, and when done, restart the http task.

Check that plugins are deployed :

tell http osgi ss oauth2

You should see something like this :

> tell http osgi ss oauth
[1C04:0002-1C08] 28/09/2017 14:27:39   Framework is launched.
[1C04:0002-1C08] 28/09/2017 14:27:39   id       State       Bundle
[1C04:0002-1C08] 28/09/2017 14:27:39   95       <<LAZY>>    com.github.lhervier.domino.oauth.server_1.0.0.qualifier
[1C04:0002-1C08] 28/09/2017 14:27:39   96       RESOLVED    com.github.lhervier.domino.oauth.external.commons_io_2.5.0
[1C04:0002-1C08] 28/09/2017 14:27:39   99       RESOLVED    com.github.lhervier.domino.oauth.external.nimbus_jose_jwt_4.37.1