Skip to content

mdorn/okta-dev-workshop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 

Repository files navigation

http://bit.ly/okta-dev-workshop

Prerequisites:

Sample app prerequisites:

  • Install Node.js (version 12 as of this writing)

Table of Contents

OAuth 2.0 Exercise

  • Before starting, import the "API Access Management (OAuth 2.0)" collection from the Okta Postman collections page.
  • You can visualize the flow we'll be using here.

Authorization Code Flow

In Okta:

  • Create a new "Web" Application
  • Go to Applications > Add Application > Web
    • Add a login redirect URI: https://oidcdebugger.com/debug
    • Ensure the "Authorization Code" grant type is selected.
    • Copy the Client ID and Client secret to a handy location.
    • Click on the "Assignments" tab, then Assign > Assign to Groups > choose "Everyone"
  • Get the Authorization Server information.
    • Go to API > Authorization Servers
    • Copy the Issuer URI for your "default" authorization server to a handy location. It looks something like this: https://dev-120098.okta.com/oauth2/default
    • Append /v1/authorize and /v1/token to the above URL and keep those URLs handy.

In OIDC Debugger tool:

  • Begin the OAuth flow
    • Go to https://oidcdebugger.com and fill in the form with the following values:
      • Authorize URI: [your authorization server path]/v1/authorize
      • Redirect URI: https://oidcdebugger.com/debug
      • Client ID: Your app client ID created in step #1 above.
      • Scope: openid profile email
      • State: foo or any other value
      • Click "Send request"
    • Copy the "authorization code" to a convenient location.

NOTE: this code will expire in a minute so if you don’t perform the following steps soon, you may have to repeat the steps above to generate a new code.

Authorization Code Exchange

In Postman

  • Import the Okta Dev environment for Postman: http://bit.ly/okta-dev-workshop-postman
  • change the following values to reflect your Okta tenant and OIDC app created above:
    • url
    • clientId
    • clientSecret

Now:

  • Find the "Get Access Token with Code" request in your Postman Collections.
  • In the "Body" tab, replace the "code" value with the authorization code returned in the previous step.
  • Click "Send"
  • Right-click the access token value from the response (the value between quotes) and set the the accessToken value in your environment. Also copy it to your clipboard.

Token Introspection

In Postman:

  • Find the "Introspect Token" request in your Postman Collections.
  • Click "Send"
  • Note the token has been decoded and validated by Okta. In production you're more likely to validate the token with your own application code. See Validate Access Tokens in the developer documentaiton.
  • Note for development purposes you can also inspect the token in a tool like https://jsonwebtoken.io -- try pasting the token into that tool.

Custom Scopes

In Okta:

  • Define a custom scope in your authorization server:
    • Go to API > Authorization Servers > default > Scopes > Add Scope
    • Give the scope a name messages and add a description (e.g. "Access messages")
  • Repeat the steps above to get an access token, starting with the OIDC Debugger tool, this time add the messages scope to "Scopes" in the debugger.
  • Inspect the token and notice the scope was returned.

NOTE: I can request this scope because I have an extremely permissive Default Access Policy for my Authorization server. In a real-world scenario I might restrict access to this scope based on Group memberships (e.g. to users who belong to a "Messages" group) by adding a rule to the default Access Policy for my default Authorization Server.

PKCE Flow

TODO

Okta Sign-In Widget Exercise

In Glitch:

In Okta:

  • Create a new SPA OIDC client
    • Go to Applications > Add Application > Single-Page app
    • Add your Glitch app URL as the login redirect URI: e.g. https://zinc-frown.glitch.me (NOTE: this is normally a particular URL in your app that will handle the auth codes and tokens, in this case for simplicity it's just the root path.)
    • Ensure the "Implicit" grant types are selected.
    • Copy the Client ID to a handy location.
    • Click on the "Assignments" tab, then Assign > Assign to Groups > choose "Everyone"
  • Add a trusted origin:
    • Go to API > Trusted Origins > Add Origin, add your Glitch app URL as a trusted origin URL for both CORS and Redirect.

In Glitch:

  • Modify index.html

Before </head> add:

<script src="https://global.oktacdn.com/okta-signin-widget/2.21.0/js/okta-sign-in.min.js" type="text/javascript"></script>
<link href="https://global.oktacdn.com/okta-signin-widget/2.21.0/css/okta-sign-in.min.css" type="text/css" rel="stylesheet"/>

In <body> add:

<div id="okta-login-container"></div>

Move script.js reference down to line above </body>:

  • Modify script.js, adding the following code and filling in the configuration values to correpond to your own environment.
var oktaSignIn = new OktaSignIn({
  baseUrl: "{ OKTA ORG URL }",
  clientId: "{ OIDC CLIENT ID }",
  logo: '//logo.clearbit.com/okta.com',
  authParams: {
    issuer: "{ OKTA ORG URL }/oauth2/default",
    responseType: ['token', 'id_token'],
    scopes: ['email', 'profile', 'openid'],
    display: 'page'
  }
});
if (oktaSignIn.token.hasTokensInUrl()) {

  oktaSignIn.token.parseTokensFromUrl(
    function success(tokens) {
      // Save the tokens for later use, e.g. if the page gets refreshed:
      // Add the token to tokenManager to automatically renew the token when needed
      tokens.forEach(token => {
        if (token.idToken) {
          oktaSignIn.tokenManager.add('idToken', token);
        }
        if (token.accessToken) {
          oktaSignIn.tokenManager.add('accessToken', token);
        }
      });

      // Say hello to the person who just signed in:
      var idToken = oktaSignIn.tokenManager.get('idToken');
      var accessToken = oktaSignIn.tokenManager.get('accessToken');
      console.log(accessToken);
      document.getElementById('okta-login-container').innerHTML = 'Hello, ' + idToken.claims.email;
      // Remove the tokens from the window location hash
      window.location.hash='';
    },
    function error(err) {
      // handle errors as needed
      console.error(err);
    }
  );
} else {
  oktaSignIn.session.get(function (res) {
    // Session exists, show logged in state.
    if (res.status === 'ACTIVE') {
      document.getElementById('okta-login-container').innerHTML = 'Welcome back, ' + res.login;
      return;
    }
    // No session, show the login form
    oktaSignIn.renderEl(
      { el: '#okta-login-container' },
      function success(res) {
        // Nothing to do in this case, the widget will automatically redirect
        // the user to Okta for authentication, then back to this page if successful
      },
      function error(err) {
        // handle errors as needed
        console.error(err);
      }
    );
  });
}
  • Go to your new Glitch project site and open up dev tools.
  • Login using the Okta sign in widget.
  • Notice you've been logged in as your user, but look at the console for the access token; note that tokens have been stored in Developer Tools > Application > Local Storage
  • Go to https://www.jsonwebtoken.io/ and paste the access token to inspect it.

Sample App Exercise

NOTE: The purpose of this exercise is to show an example front-end application interacting with an API backend. In this example, React is used as the front-end example and Node.js/Express for the backend, but you could also use other Sample Apps for other platforms (e.g. Angular, .NET, Java, etc.)

Prerequisites

  • Ensure Node.js is installed (version 12 as of this writing).

References:

In Okta:

  • Create a new PKCE OIDC client
    • Go to Applications > Add Application > Native
    • Ensure the "Authorization Code" grant type is selected.
    • Ensure redirect URI is: http://localhost:8080/implicit/callback
    • Ensure "Use PKCE" is enabled
    • Copy the Client ID to a handy location.

Set up Node.js resource server app

In a terminal window:

git clone https://github.com/okta/samples-nodejs-express-4
cd samples-nodejs-express-4/
npm install
  • Create a file called testenv in the root directory of the project and populate it with the following values:
ISSUER=https://SUBDOMAIN.okta.com/oauth2/default
SPA_CLIENT_ID=YOUR_PKCE_CLIENT_ID

Start the server:

npm run resource-server

NOTE: In a real world scenario, the resource server would want to validate the token for the existence of the messages scope before granting access (among other validations), either via application code or via an API Gateway. The Sample App may or may not be doing this for you.

Set up React front end app

In a new terminal window:

git clone https://github.com/okta/samples-js-react
cd samples-js-react/custom-login
npm install

Create a .env in the custom-login directory with the following variables populated with the values for environment:

ISSUER=https://SUBDOMAIN.okta.com/oauth2/default
CLIENT_ID=YOUR_PKCE_CLIENT_ID

Start the app server:

npm start
  • Your app is now running at http://localhost:8080
  • Login and click on "messages" to see your app sending an access token to the API.

NOTE: If you open Chrome Developer Tools (or equivalent in another browser) you can view the Network traffic and see that the access token is being sent as the Bearer: value in the Authorization header, and view the JSON response returned from the resource server.

Hooks Exercise

This exercise will show a registration inline hook in action.

In Glitch:

  • Create a new project: New Project > hello-express
  • Add a file called registration.json to the root of your project, with the following contents:
{
   "commands":[
      {
         "type":"com.okta.user.profile.update",
         "value":{
            "employeeNumber": "12345"
         }
      }
   ]
}
  • Modify server.js:
app.use(express.json());

app.all("/registration", function(request, response) {
  console.log(JSON.stringify(request.body));
  const contents = fs.readFileSync(__dirname + "/registration.json", "utf8");
  response.json(JSON.parse(contents));
});
  • Click Show > In a New Window, and append registration to the end of the URL e.g. https://fair-snowshoe.glitch.me/registration Copy this URL to your clipboard.

In Okta:

  • Add the hook:

    • Go to Workflow > Inline Hooks > Add Inline Hook > Registration
    • Give it a name (e.g. "Add Employee Code") and paste the URL you copied above e.g. https://fair-snowshoe.glitch.me/registration. Our hook endpoint is only for demo purposes so it isn't protected and doesn't require authentication.
  • Enable self-service registration at Users > Registration.

    • Click edit and change the "Extension" value to the hook you just created. Click Save.
  • In a new browser session, go to your instance's self-hosted login page and click "Sign Up" at the bottom of the form.

  • Create a new user. It's not necessary to complete the registration; an unverified user has been created

Back in your Okta admin console:

  • Go to Users > People and find the user who just registered.
  • Click the user > Profile tab, and scroll down to see that the "Employee number" value has been populated by the call to the external HTTP endpoint by the hook.

NOTE: If you observe the console your in Glitch app when registering a user, you can see the payload sent by Okta when the user registers. In a real-world scenario rather than simply returning the contents of a JSON file, your /registration hook endpoint would process this registration data and take appropriate action, including deciding whether or not to permit the registration.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published