Skip to content

Commit

Permalink
feat(openid-client-helper.js): Added utility for openid client strate…
Browse files Browse the repository at this point in the history
…gy initialization

feat #206
  • Loading branch information
kdhttps committed Feb 12, 2021
1 parent c83323f commit da25ac3
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 1 deletion.
36 changes: 36 additions & 0 deletions config/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,42 @@ const passportConfigAuthorizedResponse = {
issuer: 'urn:test:one',
redisCacheOptions: '{"host":"127.0.0.1", "port":6379}'
}
}, {
id: 'oidccedev6',
displayName: 'openid-client-ce-dev6-passport',
type: 'openid-client',
mapping: 'openid-client',
passportStrategyId: 'openid-client',
enabled: true,
callbackUrl: 'https://chris.gluuthree.org/passport/auth/oidccedev6/callback',
requestForEmail: false,
emailLinkingSafe: false,
options: {
client_id: 'b4e0f241-a8c1-4c75-8fc8-4ae7163e9695',
client_secret: 'nmGIw7bAIKjrACXODzjPJyfYDaECAWSYzE1Temqz',
redirect_uris: '["https://chris.gluuthree.org/passport/auth/oidccedev6/callback"]',
scope: '["openid", "email", "profile"]',
issuer: 'https://gluu.test.ce6.local.org',
token_endpoint_auth_method: 'client_secret_post'
}
}, {
id: 'oidccedev6privatejwt',
displayName: 'openid-client-ce-dev6-passport',
type: 'openid-client',
mapping: 'openid-client',
passportStrategyId: 'openid-client',
enabled: true,
callbackUrl: 'https://chris.gluuthree.org/passport/auth/oidccedev6privatejwt/callback',
requestForEmail: false,
emailLinkingSafe: false,
options: {
client_id: 'b4e0f241-a8c1-4c75-8fc8-4ae7163e9695',
client_secret: 'nmGIw7bAIKjrACXODzjPJyfYDaECAWSYzE1Temqz',
redirect_uris: '["https://chris.gluuthree.org/passport/auth/oidccedev6privatejwt/callback"]',
scope: '["openid", "email", "profile"]',
issuer: 'https://gluu.test.ce6.local.org',
token_endpoint_auth_method: 'private_key_jwt'
}
}]
}

Expand Down
57 changes: 57 additions & 0 deletions server/utils/openid-client-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
const { JWK: { generateSync }, JWKS: { KeyStore, asKeyStore } } = require('jose')
const { Issuer } = require('openid-client')
const path = require('path')
const fs = require('fs')
const fileUtils = require('../utils/file-utils')
const clientJWKSFilePath = path.join(`${process.cwd()}/server`, 'jwks')

/**
* generate jwks and store it in file. file name will be like [provider.id].json
* @param {*} provider
* @returns undefined
*/
async function generateJWKS (provider) {
const keyType = generateSync('RSA')
const keyStore = new KeyStore(keyType)
const fileName = path.join(fileUtils.makeDir(clientJWKSFilePath), provider.id + '.json')
// eslint-disable-next-line security/detect-non-literal-fs-filename
if (!fs.existsSync(fileName)) {
await fileUtils.writeDataToFile(fileName, JSON.stringify(keyStore.toJWKS(true)))
}
}

const clients = []

/**
* Initialize and get issuer.client object to initialize openid-client passport strategy
* @param {*} provider
* @returns issuer.client
*/
async function getClient (provider) {
const { options } = provider
let client = clients.find(c => c.id === provider.id)
if (client) {
return client.client
}

const issuer = await Issuer.discover(options.issuer)

if (options.token_endpoint_auth_method && options.token_endpoint_auth_method === 'private_key_jwt') {
// generate jwks
await generateJWKS(provider)
// eslint-disable-next-line security/detect-non-literal-require
const jwks = require(path.join(fileUtils.makeDir(clientJWKSFilePath), `${provider.id}.json`))
const ks = asKeyStore(jwks)
client = new issuer.Client(options, ks.toJWKS(true))
} else {
client = new issuer.Client(options)
}

clients.push({ id: provider.id, client })
return client
}

module.exports = {
getClient,
generateJWKS
}
2 changes: 1 addition & 1 deletion test/openid-client-helper.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe('Test OpenID Client Helper', () => {

it('we have now already client initialize so we should get client from state', async () => {
const client = await getClient(testProvider)
assert.exists(client, 'failed to make client for openid-client strategy')
assert.exists(client, 'failed to get client for openid-client strategy')
const strategy = new Strategy({ client }, () => {})
assert.exists(strategy, 'Failed to create strategy')
})
Expand Down

0 comments on commit da25ac3

Please sign in to comment.