Skip to content

Commit

Permalink
feat(xo-server-auth-oidc): OpenID Connect authentication plugin
Browse files Browse the repository at this point in the history
Fixes #6627
  • Loading branch information
julien-f committed Feb 23, 2023
1 parent c8b29da commit fad2952
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
> Users must be able to say: “Nice enhancement, I'm eager to test it”
- [VM/Advanced] Warning message when enabling Windows update tools [#6627](https://github.com/vatesfr/xen-orchestra/issues/6627) (PR [#6681](https://github.com/vatesfr/xen-orchestra/issues/6681))
- [Plugin/auth-oidc] [OpenID Connect](<https://en.wikipedia.org/wiki/OpenID#OpenID_Connect_(OIDC)>) authentication plugin [#6641](https://github.com/vatesfr/xen-orchestra/issues/6641) (PR [#6684](https://github.com/vatesfr/xen-orchestra/issues/6684))

### Bug fixes

Expand All @@ -33,6 +34,7 @@
<!--packages-start-->

- xo-cli minor
- xo-server-auth-oidc minor
- xo-web minor

<!--packages-end-->
11 changes: 11 additions & 0 deletions packages/xo-server-auth-oidc/.USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
This plugin allows users to authenticate to Xen-Orchestra using [OpenID Connect](<https://en.wikipedia.org/wiki/OpenID#OpenID_Connect_(OIDC)>).

The first time a user signs in, XO will create a new XO user with the
same identifier.

Like all other xo-server plugins, it can be configured directly via
the web interface, see [the plugin documentation](https://xen-orchestra.com/docs/plugins.html).

> Important: When registering your instance to your identity provider,
> you must configure its callback URL to
> `http://xo.company.net/signin/oidc/callback`!
1 change: 1 addition & 0 deletions packages/xo-server-auth-oidc/.npmignore
32 changes: 32 additions & 0 deletions packages/xo-server-auth-oidc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!-- DO NOT EDIT MANUALLY, THIS FILE HAS BEEN GENERATED -->

# xo-server-auth-oidc

## Usage

This plugin allows users to authenticate to Xen-Orchestra using [OpenID Connect](<https://en.wikipedia.org/wiki/OpenID#OpenID_Connect_(OIDC)>).

The first time a user signs in, XO will create a new XO user with the
same identifier.

Like all other xo-server plugins, it can be configured directly via
the web interface, see [the plugin documentation](https://xen-orchestra.com/docs/plugins.html).

> Important: When registering your instance to your identity provider,
> you must configure its callback URL to
> `http://xo.company.net/signin/oidc/callback`!
## Contributions

Contributions are _very_ welcomed, either on the documentation or on
the code.

You may:

- report any [issue](https://github.com/vatesfr/xen-orchestra/issues)
you've encountered;
- fork and create a pull request.

## License

[AGPL-3.0-or-later](https://spdx.org/licenses/AGPL-3.0-or-later) © [Vates SAS](https://vates.fr)
101 changes: 101 additions & 0 deletions packages/xo-server-auth-oidc/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
'use strict'

const { Strategy } = require('passport-openidconnect')

// ===================================================================

const DISCOVERABLE_SETTINGS = ['authorizationURL', 'issuer', 'userInfoURL', 'tokenURL']

exports.configurationSchema = {
type: 'object',
properties: {
discoveryURL: {
description: 'If this field is not used, you will need to manually enter settings in the *Advanced* section.',
title: 'Auto-discovery URL',
type: 'string',
},
clientID: { title: 'Client identifier (key)', type: 'string' },
clientSecret: { title: 'Client secret', type: 'string' },

advanced: {
title: 'Advanced',
type: 'object',
properties: {
authorizationURL: { title: 'Authorization URL', type: 'string' },
callbackURL: {
description: 'Default to https://<xo.company.net>/signin/oidc/callback`.',
title: 'Callback URL',
type: 'string',
},
issuer: { title: 'Issuer', type: 'string' },
tokenURL: { title: 'Token URL', type: 'string' },
userInfoURL: { title: 'User info URL', type: 'string' },
usernameField: {
default: 'username',
description: 'Field to use as the XO username',
title: 'Username field',
type: 'string',
},
},
},
},
required: ['clientID', 'clientSecret'],
anyOf: [{ required: ['discoveryURL'] }, { properties: { advanced: { required: DISCOVERABLE_SETTINGS } } }],
}

// ===================================================================

class AuthOidc {
#conf
#unregisterPassportStrategy
#xo

constructor(xo) {
this.#xo = xo
}

async configure({ advanced, ...conf }, { loaded }) {
this.#conf = { callbackURL: '/signin/oidc/callback', ...advanced, ...conf }

if (loaded) {
await this.unload()
await this.load()
}
}

async load() {
const xo = this.#xo
const { discoveryURL, usernameField, ...conf } = this.#conf

if (discoveryURL !== undefined) {
const res = await this.#xo.httpRequest(discoveryURL)
const data = await res.json()

for (const key of DISCOVERABLE_SETTINGS) {
if (!conf[key]) {
conf[key] = data[key.endsWith('URL') ? key.slice(0, -3).toLowerCase() + '_endpoint' : key]
}
}
}

this.#unregisterPassportStrategy = xo.registerPassportStrategy(
new Strategy(conf, async (issuer, profile, done) => {
try {
const { id, [usernameField]: name } = profile
done(null, await xo.registerUser2('oidc:' + issuer, { user: { id, name } }))
} catch (error) {
done(error.message)
}
}),
{ label: 'OpenID Connect', name: 'oidc' }
)
}

unload() {
this.#unregisterPassportStrategy()
}
}

// ===================================================================

exports.default = ({ xo }) => new AuthOidc(xo)
23 changes: 23 additions & 0 deletions packages/xo-server-auth-oidc/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"private": true,
"name": "xo-server-auth-oidc",
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/packages/xo-server-auth-oidc",
"bugs": "https://github.com/vatesfr/xen-orchestra/issues",
"repository": {
"directory": "packages/xo-server-auth-oidc",
"type": "git",
"url": "https://github.com/vatesfr/xen-orchestra.git"
},
"author": {
"name": "Vates SAS",
"url": "https://vates.fr"
},
"license": "AGPL-3.0-or-later",
"version": "0.0.0",
"engines": {
"node": ">=12"
},
"dependencies": {
"passport-openidconnect": "^0.1.1"
}
}
8 changes: 8 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -15061,6 +15061,14 @@ passport-oauth2@1.x.x:
uid2 "0.0.x"
utils-merge "1.x.x"

passport-openidconnect@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/passport-openidconnect/-/passport-openidconnect-0.1.1.tgz#83921ff5f87f634079f65262dada834af1972244"
integrity sha512-r0QJiWEzwCg2MeCIXVP5G6YxVRqnEsZ2HpgKRthZ9AiQHJrgGUytXpsdcGF9BRwd3yMrEesb/uG/Yxb86rrY0g==
dependencies:
oauth "0.9.x"
passport-strategy "1.x.x"

passport-saml@^3.2.0:
version "3.2.4"
resolved "https://registry.yarnpkg.com/passport-saml/-/passport-saml-3.2.4.tgz#e8e9523f954988a3a47d12e425d7fa0f20a74dc9"
Expand Down

0 comments on commit fad2952

Please sign in to comment.