-
Notifications
You must be signed in to change notification settings - Fork 3
OIDC example using openid-client and @apostrophecms/passport-bridge version 1.5.0-beta.1 #130
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| import * as client from 'openid-client'; | ||
| import { | ||
| Strategy | ||
| } from 'openid-client/passport' | ||
|
|
||
| export default { | ||
| options: { | ||
| create: { | ||
| role: 'guest' | ||
| }, | ||
| strategies: [ | ||
| { | ||
| async factory(params, fn) { | ||
| const issuer = new URL(process.env.OIDC_ISSUER); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because of discovery, all we need is a URL to the provider site (OIDC_ISSUER), OIDC_CLIENT_ID, and OIDC_CLIENT_SECRET. |
||
| const config = await client.discovery( | ||
| issuer, | ||
| process.env.OIDC_CLIENT_ID, | ||
| process.env.OIDC_CLIENT_SECRET | ||
| ); | ||
| const { | ||
| // injected into params by passport-bridge | ||
| callbackURL | ||
| } = params; | ||
| const s = new Strategy({ | ||
| config, | ||
| scope: 'openid email', | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can beef this up if you have other scopes of interest. |
||
| callbackURL | ||
| }, (tokens, callback) => { | ||
| const claims = tokens.claims(); | ||
|
|
||
| // oidc provides: | ||
|
|
||
| // sid | ||
| // name: 'Tom Boutell', | ||
| // preferred_username: 'tomtest1', | ||
| // given_name: 'Tom', | ||
| // family_name: 'Boutell', | ||
| // email: 'tom+tomtest1@apostrophecms.com' | ||
|
|
||
| // But oauth providers provide (and passport-bridge expects, by default): | ||
|
|
||
| // id | ||
| // displayname | ||
| // username | ||
| // firstName | ||
| // lastName | ||
| // "emails" or "email" | ||
|
|
||
| const profile = { | ||
| id: claims.sid, | ||
| displayName: claims.name, | ||
| firstName: claims.given_name, | ||
| lastName: claims.family_name, | ||
| email: claims.email, | ||
| username: claims.preferred_username | ||
| }; | ||
|
|
||
| return fn(null, tokens.access_token, tokens.refresh_token, profile, callback); | ||
| }); | ||
| // The strategy sets it to the hostname, override so we can predict the URLs | ||
| s.name = 'oidc'; | ||
| return s; | ||
| }, | ||
| // Required when using a factory function | ||
| name: 'oidc', | ||
| // These would show up in "params" above, we chose to use environment | ||
| // variables instead | ||
| options: {}, | ||
| // Use the user's email address as their identity | ||
| match: 'email', | ||
| // Strategy-specific options that must be passed to the authenticate middleware. | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually you should be able to skip this "authenticate" property because it is covered by the factory function. |
||
| // See the documentation of the strategy module you are using | ||
| authenticate: { | ||
| scope: [ 'openid', 'email' ] | ||
| } | ||
| } | ||
| ] | ||
| } | ||
| } | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,10 +7,16 @@ | |
|
|
||
| {% block main %} | ||
| <section class="page-home"> | ||
| <h1>User Info</h1> | ||
| <ul> | ||
| {% for name, value in data.user %} | ||
| <li>{{ name }}: {{ value }}</li> | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just showing we get access. |
||
| {% endfor %} | ||
| </ul> | ||
| {% if data.theme === 'demo' %} | ||
| {% include 'theme-demo:welcome.html' %} | ||
| {% endif %} | ||
|
|
||
| {% area data.page, 'main' %} | ||
| </section> | ||
| {% endblock %} | ||
| {% endblock %} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New factory option allows us to pass our own async function that returns a fully initialized strategy object. This allows us to use OIDC discovery