Objective

  • To create a test SPA (Single Page Application) and integrate OKTA with OIDC protocol and authorization code flow with PKCE
  • Develop CI/CD pipe line with Github for easy deployment.
  • Enable Federation broker mode for immediate access to all users in OKTA

This document will help developers understand the work flow for integrating the custom SPA applications with OKTA using OIDC authorization code flow with PKCE

Details

Prerequisites

  • Install Git
  • Install node js
  • Install VS code
  • OKTA tenant

Flow sequence

SPA creates code_verifier and code_challenge

SPA sends code_challenge to Okta

Okta stores challenge and authenticates user

Okta issues authorization_code

SPA sends authorization_code + code_verifier

Okta verifies verifier

Okta issues ID Token and Access Token

Integration model

Identity provider: OKTA

Service provider: SPA

Authentication protocol: OIDC

Grant type: Authorization code flow with PKCE

Create test SPA application

Create SPA that have capability to handle OIDC authorization code flow and CI/CD pipe line with Github

Create folder structure

Open CMD prompt in local drive and run following commands

mkdir okta-interaction-code-spa

cd okta-interaction-code-spa

type nul > package.json

type nul > index.html

type nul > app.js

type nul > callback.html

type nul > .gitignore

mkdir .github

mkdir .github\workflows

type nul > .github\workflows\spa-ci.yml

To check the folders and files created. Run below command.

tree /f

Open the project in Visual Studio Code

Follow the steps below:

Package.json

We are importing the okta-auth-js SDK into the project for getting the code verifier, code challenger & authorization code flow objects and methods.

{

“name”: “okta-interaction-code-spa”,

“version”: “1.0.0”,

“scripts”: {

“start”: “http-server -p 3000”

},

“dependencies”: {

“@okta/okta-auth-js”: “^7.7.0”,

“http-server”: “^14.1.1”

}

}

 

Install the packages

Open the terminal and run following command

npm install

This creates

  • node_modules
  • Package-lock.json

package-lock.json records the exact versions of every installed package, including nested dependencies. This will prevent breaks during next builds.

Build the application components

Index.html

<!DOCTYPE html>

<html>

<head>

<title>Interaction Code Flow Testing</title>

</head>

<body>

<h2>Welcome to Interaction Code Flow Testing</h2>

<button onclick=”login()”>Login with Okta</button>

<script type=”module” src=”app.js”></script>

</body>

</html>

Create OIDC application in OKTA

SPA end points

Base URL: http://localhost:3000

Sign-in redirect URI / Call back URL: http://localhost:3000/callback.html

Sign-out redirect URI: http://localhost:3000

  • Login to Okta
  • Go to Applications>Applications

  • Create new OIDC app integration

 

  • Select Application Type as Single-Page Application

Copy Client ID for integrating with SPA

Client ID: : 0oa110oicxdNrfDf2698

Enable Federation Broker

Check trusted origins

  • Go to Security>API
  • Click Trusted Origins tab

Trusted origin has been created

Assign users to the application in the OKTA

  • Since federation broker is enabled, configure app sign-in policy
  • Go to the OIDC Application that was created and click Assignments

Configure App Sign-In policy

Configure Sign On Policy

Add a rule or Edit the rule

Assign the application to the policy

Add authorization server policy

Continue the SPA configurations

Navigate to VS code to access app.js

app.js

import { OktaAuth } from ‘https://cdn.skypack.dev/@okta/okta-auth-js’;

const oktaAuth = new OktaAuth({

issuer: ‘https://integrator-3863631.okta.com/oauth2/default’,

clientId: ‘0oa110oicxdNrfDf2698’,

redirectUri: ‘http://localhost:3000/callback.html’,

scopes: [‘openid’, ‘profile’, ’email’],

pkce: true

});

async function login() {

const meta = await oktaAuth.token.prepareTokenParams();

console.log(“CODE VERIFIER:”, meta.codeVerifier);

console.log(“CODE CHALLENGE:”, meta.codeChallenge);

await oktaAuth.token.getWithRedirect({

responseType: ‘code’

});

}

window.login = login;

callback.html

<!DOCTYPE html>

<html>

<head>

<title>Callback</title>

</head>

<body>

<h2>Processing login…</h2>

<script type=”module”>

import { OktaAuth } from ‘https://cdn.skypack.dev/@okta/okta-auth-js’;

const oktaAuth = new OktaAuth({

issuer: ‘https://integrator-3863631.okta.com/oauth2/default’,

clientId: ‘0oa110oicxdNrfDf2698’,

redirectUri: ‘http://localhost:3000/callback.html’,

scopes: [‘openid’, ‘profile’, ’email’],

pkce: true

});

async function handleLogin() {

const tokens = await oktaAuth.token.parseFromUrl();

console.log(“TOKENS:”, tokens);

document.body.innerHTML =

“<h2>Welcome to Interaction Code Flow Testing. You are logged in.</h2>”;

}

handleLogin();

</script>

</body>

</html>

Initiate the flow

npm start in the terminal

  • In the browser execute

http://localhost:3000/?v=2

  • Open developer tools and check console
  • SPA generated the code verifier and code challenger

  • Click on login with OKTA button
  • User is redirected to OKTA

Create CI/CD pipe line

Update spa-ci.yml

name: SPA CI/CD

on:

push:

branches:

– main

jobs:

build:

runs-on: ubuntu-latest

steps:

– name: Checkout source

uses: actions/checkout@v4

– name: Setup Node

uses: actions/setup-node@v4

with:

node-version: 20

– name: Install dependencies

run: npm install

– name: Verify project files

run: |

ls -l

test -f index.html

test -f app.js

test -f callback.html

– name: Create deploy package

run: zip -r okta-interaction-code-spa.zip .

– name: Upload artifact

uses: actions/upload-artifact@v4

with:

name: spa-package

path: okta-interaction-code-spa.zip

Update package.json

{

“name”: “okta-interaction-code-spa”,

“version”: “1.0.0”,

“type”: “module”,

“scripts”: {

“start”: “http-server -p 3000”,

“verify”: “echo SPA verification successful”

},

“dependencies”: {

“@okta/okta-auth-js”: “^7.7.0”,

“http-server”: “^14.1.1”

}

}

Create a repository in Github

Initialize Git

In the terminal run the command: git init

Add Github remote

Run the command: git remote add origin https://github.com/rmadabhushi/okta-interaction-code-spa.git

Verify remote

Run the command: git remote -v

.gitignore

Update the file to ignore node modules pushing to Github

Commit

Run the commands:

git add .

git commit -m “initial okta spa project with CI/CD”

Set main branch

Run the command: git branch -M main

Git push

Run the command: git push -u origin main

The repositories are available in Github

The files can be downloaded from the below link

rmadabhushi/okta-interaction-code-spa: okta-interaction-code-spa

Author

Rangarajan Madabhushi

Ranga Vinjamuri

Rajya Tupuri

TOP