diff --git a/Requests/.vscode/settings.json b/Requests/.vscode/settings.json new file mode 100644 index 0000000..28241c5 --- /dev/null +++ b/Requests/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "rest-client.environmentVariables": { + "$shared": { + "api": "https://localhost:6001", + "tenant": "https://localhost:5001", + "audience": "urn:calcapi" + } + } +} diff --git a/Requests/0_Basics/1_requests.http b/Requests/0_Basics/1_requests.http new file mode 100644 index 0000000..45d8857 --- /dev/null +++ b/Requests/0_Basics/1_requests.http @@ -0,0 +1,23 @@ +########## +# +# Basics (Metadata) +# +########## + + +# OpenID Provider Configuration Request +# https://openid.net/specs/openid-connect-discovery-1_0.html +# +# @name configuration +GET {{tenant}}/.well-known/openid-configuration + +### + +@jwks_uri = {{configuration.response.body.$.jwks_uri}} + +# JSON Web Key Set document +# https://tools.ietf.org/html/draft-ietf-jose-json-web-key-31 +# +# @name jwks + +GET {{jwks_uri}} diff --git a/Requests/1_Client_Credentials_Grant/1_requests.http b/Requests/1_Client_Credentials_Grant/1_requests.http new file mode 100644 index 0000000..f81c995 --- /dev/null +++ b/Requests/1_Client_Credentials_Grant/1_requests.http @@ -0,0 +1,49 @@ +########## +# +# Client Credentials Grant +# +# https://datatracker.ietf.org/doc/html/rfc6749#section-4.4 +# +########## + + +##### +# Configuration --> use Client Credentials Grant + +@client_id= worker +@client_secret = secret +@scope = calc:double + +# +##### + + +# Get Access Token for Client (double-only) +# @name token +POST {{tenant}}/connect/token +Content-Type: application/x-www-form-urlencoded + +grant_type=client_credentials +&client_id={{client_id}} +&client_secret={{client_secret}} +&scope={{scope}} + +### +# @name double + +@access_token = {{token.response.body.$.access_token}} + +# Call API +GET {{api}}/Double/2 +Authorization: Bearer {{access_token}} + + +### +# @name square + +@access_token = {{token.response.body.$.access_token}} + +# Call API +GET {{api}}/Square/2 +Authorization: Bearer {{access_token}} + diff --git a/Requests/6_Authorization_Code_with_PKCE/1_requests.http b/Requests/6_Authorization_Code_with_PKCE/1_requests.http new file mode 100644 index 0000000..db93d83 --- /dev/null +++ b/Requests/6_Authorization_Code_with_PKCE/1_requests.http @@ -0,0 +1,44 @@ +########## +# +# Authorization Code Grant with PKCE +# +# https://datatracker.ietf.org/doc/html/rfc6749#section-1.3.1 +# https://www.rfc-editor.org/rfc/rfc7636.html +# +########## + + +##### +# Configuration --> use Authorization Code Grant with PKCE +# generate custom code_challenge and code_verifier with auth-code-pkce.js + +@client_id= web +@client_secret = secret +@redirect_uri = https://localhost:5002/signin-oidc +@code_challenge = JiCfjR0ceTNiBRcxghqjnWxBwRl9o2B7ogdxpGl2tDw +@code_verifier = aj1cBUxqDQvrueJKvr-taJkWPpmuodt-kqX5Z4KukSM +@scope = openid email profile offline_access calc:double +# +##### + + +# Authorize +GET {{tenant}}/connect/authorize?state=l337&redirect_uri={{redirect_uri}}&code_challenge_method=S256&code_challenge={{code_challenge}}&client_id={{client_id}}&response_type=code&scope={{scope}}&audience={{audience}}&prompt=consent + +### + +# Get access and refresh token +# @name token + +@code = 892A6B9BB1FF2BD98A79A3E595548C687E1B8098DBA64B0E3F1DC5E183FBD154-1 + + +POST {{tenant}}/connect/token +Content-Type: application/x-www-form-urlencoded + +grant_type=authorization_code +&client_id={{client_id}} +&client_secret={{client_secret}} +&code_verifier={{code_verifier}} +&code={{code}} +&redirect_uri={{redirect_uri}} diff --git a/Requests/7_Device_Flow/1_requests.http b/Requests/7_Device_Flow/1_requests.http new file mode 100644 index 0000000..3a836d4 --- /dev/null +++ b/Requests/7_Device_Flow/1_requests.http @@ -0,0 +1,74 @@ +########## +# +# Device Authorization Grant +# +# https://datatracker.ietf.org/doc/html/rfc8628 +# +########## + + +##### +# Configuration --> use Device Code Grant + +@client_id = device +@client_secret = secret +@scope = openid email profile offline_access calc:double +@resource = urn:calcapi + +# +##### + +# Get Device Code +# @name devicecode + +POST {{tenant}}/connect/deviceauthorization +Content-Type: application/x-www-form-urlencoded + +client_id={{client_id}} +&client_secret={{client_secret}} +&scope={{scope}} +&resource={{resource}} + + +### + +@device_code = {{devicecode.response.body.$.device_code}} +@user_code = {{devicecode.response.body.$.user_code}} + +# Get Token +# @name token + +POST {{tenant}}/connect/token +Content-Type: application/x-www-form-urlencoded + +grant_type=urn:ietf:params:oauth:grant-type:device_code +&client_id={{client_id}} +&client_secret={{client_secret}} +&device_code={{device_code}} + +### + +@access_token = {{token.response.body.$.access_token}} +@id_token = {{token.response.body.$.id_token}} + +# Get Userinfo with identity token +GET {{tenant}}/connect/userinfo +Authorization: Bearer {{access_token}} + +### + +# Double Calucator API +GET https://localhost:6001/Double/3 +Authorization: Bearer {{access_token}} + +### + +# Square Calucator API +GET https://localhost:6001/Square/3 +Authorization: Bearer {{access_token}} + +### + +# Tokeninfo Calucator API +GET http://localhost:5001/api/tokeninfo +Authorization: Bearer {{access_token}} diff --git a/Requests/README.md b/Requests/README.md new file mode 100644 index 0000000..60b976e --- /dev/null +++ b/Requests/README.md @@ -0,0 +1,12 @@ +# OAuth / OpenID Connect Sample Requests + +## Prerequisites + +- [Visual Studio Code](https://code.visualstudio.com) +- [REST Client](https://marketplace.visualstudio.com/items?itemName=humao.rest-client) + +## Usage + +- Customize configuration settings in [.vscode\settings.json](.vscode/settings.json) +- Start IdentityServer in [IdentityServer](../src/IdentityServerUi)] +- Start Calculator API in [CalcApi](../src/CalcApi) diff --git a/Requests/helpers/.gitignore b/Requests/helpers/.gitignore new file mode 100644 index 0000000..7d00161 --- /dev/null +++ b/Requests/helpers/.gitignore @@ -0,0 +1,76 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless + +# FuseBox cache +.fusebox/ \ No newline at end of file diff --git a/Requests/helpers/auth-code-pkce/.devcontainer/devcontainer.json b/Requests/helpers/auth-code-pkce/.devcontainer/devcontainer.json new file mode 100644 index 0000000..9662c3e --- /dev/null +++ b/Requests/helpers/auth-code-pkce/.devcontainer/devcontainer.json @@ -0,0 +1,22 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node +{ + "name": "Node.js & TypeScript", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/typescript-node:0-20" + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "yarn install", + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/Requests/helpers/auth-code-pkce/.github/dependabot.yml b/Requests/helpers/auth-code-pkce/.github/dependabot.yml new file mode 100644 index 0000000..3a3cce5 --- /dev/null +++ b/Requests/helpers/auth-code-pkce/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "npm" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/Requests/helpers/auth-code-pkce/.github/workflows/codeql-analysis.yml b/Requests/helpers/auth-code-pkce/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..6e4d100 --- /dev/null +++ b/Requests/helpers/auth-code-pkce/.github/workflows/codeql-analysis.yml @@ -0,0 +1,74 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ "main" ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ "main" ] + schedule: + - cron: '20 17 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{matrix.language}}" diff --git a/Requests/helpers/auth-code-pkce/.gitignore b/Requests/helpers/auth-code-pkce/.gitignore new file mode 100644 index 0000000..7d00161 --- /dev/null +++ b/Requests/helpers/auth-code-pkce/.gitignore @@ -0,0 +1,76 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless + +# FuseBox cache +.fusebox/ \ No newline at end of file diff --git a/Requests/helpers/auth-code-pkce/auth-code-pkce.js b/Requests/helpers/auth-code-pkce/auth-code-pkce.js new file mode 100644 index 0000000..089f310 --- /dev/null +++ b/Requests/helpers/auth-code-pkce/auth-code-pkce.js @@ -0,0 +1,15 @@ +const crypto = require('crypto'); +const base64url = require('base64url'); + +var code_verifier = randomString(); + +var hash = crypto.createHash('sha256').update(code_verifier).digest(); +var code_challenge = base64url.encode(hash) + +console.log(`code challenge: ${code_challenge}`); +console.log(`code verifier: ${code_verifier}`); + +/** @returns {string} crypto-generated base64 string */ +function randomString() { + return base64url.encode(crypto.randomBytes(32)) +} \ No newline at end of file diff --git a/Requests/helpers/auth-code-pkce/package-lock.json b/Requests/helpers/auth-code-pkce/package-lock.json new file mode 100644 index 0000000..531ac8a --- /dev/null +++ b/Requests/helpers/auth-code-pkce/package-lock.json @@ -0,0 +1,24 @@ +{ + "name": "auth-code-pkce", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "auth-code-pkce", + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "base64url": "^3.0.1" + } + }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "engines": { + "node": ">=6.0.0" + } + } + } +} diff --git a/Requests/helpers/auth-code-pkce/package.json b/Requests/helpers/auth-code-pkce/package.json new file mode 100644 index 0000000..c71102b --- /dev/null +++ b/Requests/helpers/auth-code-pkce/package.json @@ -0,0 +1,19 @@ +{ + "name": "auth-code-pkce", + "version": "1.0.0", + "description": "PKCE utility for OAuth 2.0 authorization code grant", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "oauth2", + "oidc", + "pkce", + "authorization code" + ], + "author": "Daniel Wagner ", + "license": "MIT", + "dependencies": { + "base64url": "^3.0.1" + } +}