Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update sample to work with Heroku #2

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "Okta Node.js OIDC Sample",
"description": "A barebones Node.js app showing how to integrate with Okta via OIDC",
"repository": "https://github.com/jpf/okta-oidc-sample",
"logo": "https://www.okta.com/sites/all/themes/Okta/images/blog/Auras/Okta_Aura_Solid_BrightBlue_40percent.png",
"success_url": "/welcome",
"env": {
"ISSUER": {
"description": "Access Token Issuer URL",
"value": "https://example.oktapreview.com"
},
"AUDIENCE": {
"description": "Access Token Audience URI",
"value": "ANRZhyDh8HBFN5abN6Rg"
},
"IDP": {
"description": "Okta ID for the Social IdP",
"value": "0oa4ftg4vzKlWHHEJ0h7"
},
"AUTHZISSUER": {
"description": "Alternate Authorization URL",
"value": "0oa4ftg4vzKlWHHEJ0h7"
},
"APITOKEN": {
"description": "Okta Organization SSWS API Token for Social IdP Callbacks",
"required": false,
"value": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
},
"keywords": ["node", "express", "oidc", "okta"]
}
9 changes: 9 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"issuer": "https://example.oktapreview.com",
"audience": "ANRZhyDh8HBFN5abN6Rg",
"apiToken": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"authzIssuer": "https://example.oktapreview.com/oauth2/aus8q4gst8vbUGzFp0h7",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't this be cleaned up by setting the issuer to your custom authorization server? I don't see why we need two issuers here.

"idp": "0oa4ftg4vzKlWHHEJ0h7",
"widgetScopes": ["openid", "email", "profile", "phone", "address", "groups"],
"protectedScope": "api:read"
}
21 changes: 0 additions & 21 deletions js/config.js

This file was deleted.

12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
{
"name": "okta-oidc-sample",
"version": "0.0.2",
"version": "0.0.3",
"engines": {
"node": "8.2.x"
},
"description": "Sample OpenID Connect Web Server",
"private": true,
"main": "server.js",
"scripts": {
"start": "node server.js | bunyan -o short"
"start": "node server.js --config config.json | bunyan -o short"
},
"author": "Karl McGuinness",
"license": "MIT",
"dependencies": {
"body-parser": "^1.15.0",
"bunyan": "^1.8.12",
"ejs": "^2.5.6",
"express": "^4.15.3",
"express-session": "^1.15.3",
"express-state": "^1.4.0",
"helmet": "^3.8.1",
"morgan": "^1.7.0",
"passport": "https://github.com/mcguinness/passport.git",
"passport-oauth2-jwt-bearer": "https://github.com/mcguinness/passport-oauth2-jwt-bearer.git",
"yargs": "^6.3.0"
"yargs": "^7.1.0"
}
}
42 changes: 32 additions & 10 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ This sample demonstrates the OpenID Connect implicit flow:
- Refresh Token: Uses the current session with Okta to obtain a new id_token (JWT) via a hidden iframe
- Request Protected Resource (API): Uses the `id_token` as an OAuth2 Bearer Access Token to request a protected resources from an API (you must first authenticate)

These scenarios are enabled by the `okta_post_message` custom `response_mode` for the [OpenID Connect Authentication Request](http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest) which uses [HTML5 Window Messaging] (https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) and a hidden iframe to return the [id_token] (http://openid.net/specs/openid-connect-core-1_0.html#AuthResponse) to the Single Page Web App (SPA) without refreshing or redirecting the page.
These scenarios are enabled by the `okta_post_message` custom `response_mode` for the [OpenID Connect Authentication Request](http://openid.net/specs/openid-connect-core-1_0.html#AuthRequest) which uses [HTML5 Window Messaging](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) and a hidden iframe to return the [id_token](http://openid.net/specs/openid-connect-core-1_0.html#AuthResponse) to the Single Page Web App (SPA) without refreshing or redirecting the page.

See [postMessageCallback](https://github.com/mcguinness/okta-oidc-sample/blob/master/js/OktaAuthRequireJquery.js#L1118) for implementation details of how the `okta_post_message` response_mode works

Expand All @@ -25,6 +25,27 @@ This sample demonstrates the OpenID Connect implicit flow with the Okta Sign-In

You can find the main javascript code and html in `/js/widget-app.js` and html in `widget.html`

# Deploy to Heroku

Prerequisites:
1. The **name of your Okta org** (e.g. `http://example.okta.com`)
2. A **Client ID**:
- Applications>Add Application
- Click the **"Create New App"** button
- Select **"Single Page App (SPA)"** as the Platform
- Select **"OpenID Connect"** and click the "Create" button
- Enter a name for the application such as "Sample OIDC App" and click **"Next"**
- Copy the **"Client ID"** for your new application
- Navigate to the **Groups** tab for the application and assign to the **Everyone** group

Once you have your **Okta org** and **Client ID**, click the button below and follow the prompts:

[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)

# Local development

Follow the steps below to install this sample on your local development machine:

## Prerequisites

1. Install [node.js and npm](https://nodejs.org/en/download/) on your developer machine
Expand All @@ -43,18 +64,20 @@ You can find the main javascript code and html in `/js/widget-app.js` and html i
2. Click the **"Create New App"** button
3. Select **"Single Page App (SPA)"** as the Platform
4. Select **"OpenID Connect"** and click the "Create" button
5. Enter a name for the app such as "Sample OIDC App" and click **"Next"**
5. Enter a name for the application such as "Sample OIDC App" and click **"Next"**
6. Add the following redirect URIs and click **"Finish"**
- "http://localhost:8080/"
- "http://localhost:8080/oidc"
- "http://localhost:8080/oidc.html"
- "http://localhost:8080/widget.html"
```
http://localhost:8080/
http://localhost:8080/oidc
http://localhost:8080/oidc.html
http://localhost:8080/widget.html
```
7. Copy the **"Client ID"** for your new application
8. Navigate to the Groups tab for the new app and assign the everyone group
8. Navigate to the **Groups** tab for the application and assign to the **Everyone** group

3. Update `/js/config.js` with your Okta organization URL and the **"Client ID"** you copied from your OIDC Application in step 7

```
```javascript
return {
orgUrl: 'https://example.oktapreview.com',
clientId: 'ANRZhyDh8HBFN5abN6Rg'
Expand All @@ -75,7 +98,7 @@ The Okta Sign-In Widget also supports Social Authentication. You need to first

When initializing the the widget you then add the IdP as an additional param with the `id` and `type` (e.g. `FACEBOOK`, `GOOGLE`, or `LINKEDIN`) which controls the branding of the button

```
```javascript
oktaSignIn.renderEl(
{
idps: [
Expand Down Expand Up @@ -126,4 +149,3 @@ Update `/js/config.js` with an [API Token](https://developer.okta.com/docs/api/g
11. Change the mapping from "Apply mapping on user create only" to "Apply mapping on user create or update"
12. Click **Save Mappings**
13. Click **Apply Updates Now**

61 changes: 38 additions & 23 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const helmet = require('helmet');
const passport = require('passport');
const JwtBearerStrategy = require('passport-oauth2-jwt-bearer').Strategy;
const request = require('request');
const OktaConfig = require('./js/config');

/**
* Arguments
Expand All @@ -31,39 +30,46 @@ var argv = yargs
issuer: {
description: 'Access Token Issuer URL',
required: true,
alias: 'iss',
default: OktaConfig.orgUrl
alias: ['iss', 'orgUrl']
},
audience: {
description: 'Acceess Token Audience URI',
description: 'Access Token Audience URI',
required: true,
alias: 'aud',
default: OktaConfig.clientId
alias: ['aud', 'clientId']
},
widgetScopes: {
array: true,
description: 'Scopes for the Okta Sign-In Widget to request'
},
scope: {
description: 'OAuth 2.0 Scope for Protected Resource',
required: true,
alias: 'scp',
default: OktaConfig.resourceScope
alias: ['scp', 'protectedScope'],
},
apiToken: {
description: 'Okta Organization SSWS API Token for Social IdP Callbacks',
required: true,
alias: 'ssws',
default: OktaConfig.apiToken
},
authzIssuer: {
description: 'Alternate Authorization URL',
},
idp: {
description: 'Okta ID for the Social IdP',
}
})
.config()
.example('\t$0 --iss https://example.okta.com --aud ANRZhyDh8HBFN5abN6Rg', '')
.env('')
.argv;

const issuerUrl = url.parse(argv.issuer);
const metadataUrl = argv.issuer + '/.well-known/openid-configuration';
const orgUrl = issuerUrl.protocol + '//' + issuerUrl.host + (issuerUrl.port ? ':' + issuerUrl.port : '');

console.log();
console.log('Listener Port:\n\t' + argv.port);
console.log('Issuer URL:\n\t' + argv.issuer);
console.log('Audience URI:\n\t' + argv.audience);

const issuerUrl = url.parse(argv.issuer);
const metadataUrl = argv.issuer + '/.well-known/openid-configuration';
const orgUrl = issuerUrl.protocol + '//' + issuerUrl.host + (issuerUrl.port ? ':' + issuerUrl.port : '');

console.log('Metadata URL:\n\t' + metadataUrl);
console.log('Organization URL:\n\t' + orgUrl);
console.log();
Expand All @@ -83,6 +89,8 @@ const sessionHandler = require('express-session')({
saveUninitialized: true
});

app.enable('trust proxy');

/**
* Middleware
*/
Expand All @@ -98,6 +106,21 @@ app.use(passport.initialize());
* Routes
*/

app.get('/js/config.js', sessionHandler, function(req, res, next) {
res.setHeader('Content-Type', 'application/javascript');
return res.render('config', {argv: argv});
});

app.get('/welcome', sessionHandler, function(req, res, next) {
var thisAppUrl = req.protocol + "://" + req.headers.host

return res.render('welcome', {
thisAppUrl: thisAppUrl,
oktaAdminOrg: argv.issuer.replace('.', '-admin.'),
argv: argv
});
});

app.get('/social/callback', sessionHandler, function(req, res, next) {
const txId = req.query.tx_id;
console.log('Fetching IdP transaction %s', txId);
Expand Down Expand Up @@ -231,11 +254,3 @@ request({
});

});








8 changes: 8 additions & 0 deletions views/config.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
(define([], {
orgUrl: '<%- argv.issuer %>',
clientId: '<%- argv.audience %>',
authzIssuer: '<%- argv.authzIssuer %>',
idp: '<%- argv.idp %>',
scopes: <%- JSON.stringify(argv.widgetScopes) %>,
protectedScope: '<%- argv.protectedScope %>'
}));
37 changes: 37 additions & 0 deletions views/welcome.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Final Steps</title>
</head>
<body>
<h1>You're almost done!</h1>
You just need to complete these steps to get this app working with Okta:
<ol>
<li>
In the
<a href="<%= oktaAdminOrg %>/admin/access/api/trusted_origins">
Trusted Origins section of your Okta organization</a>,
grant
<a href="http://developer.okta.com/docs/api/getting_started/enabling_cors.html">
CORS access
</a>
to: <code><%= thisAppUrl %></code>
</li>
<li>
Make sure that the
<a href="<%= oktaAdminOrg %>/admin/app/oidc_client/instance/<%= argv.audience %>/#tab-general">
OpenID Connect Application you created</a>
has the following URLs registered as Login redirect URIs:
<ul>
<li><code><%= thisAppUrl %>/</code></li>
<li><code><%= thisAppUrl %>/oidc</code></li>
<li><code><%= thisAppUrl %>/oidc.html</code></li>
<li><code><%= thisAppUrl %>/widget.html</code></li>
</ul>
</li>
</ol>
</body>
</html>