From 633622e08583fdb05a6a2cbd8f88c1d30330b469 Mon Sep 17 00:00:00 2001 From: vzakharchenko Date: Wed, 7 Jul 2021 22:13:25 +0300 Subject: [PATCH 1/7] moved lambda@edge to https://github.com/vzakharchenko/keycloak-api-gateway --- README.md | 380 +-- __tests__/src/edge/lambdaEdgeUtilsTest.js | 183 -- __tests__/src/edge/lamdaEdgeTest.js | 71 - __tests__/src/edge/routerTest.js | 25 - __tests__/src/edge/routers/CallbackTest.js | 203 -- __tests__/src/edge/routers/LogoutTest.js | 62 - __tests__/src/edge/routers/routesTest.js | 186 -- .../routers/utils/redirectAuthServerTest.js | 276 -- .../src/edge/session/SessionManagerTest.js | 146 -- .../edge/session/localSessionStorageTest.js | 27 - __tests__/src/utils/TokenUtilsTest.js | 60 - __tests__/src/utils/cookiesUtilsTest.js | 89 - example/keycloak-cloudfront-portal/README.md | 58 - .../babel.config.js | 43 - example/keycloak-cloudfront-portal/index.html | 10 - .../keycloak-cloudfront-cdk/cdk.json | 3 - .../keycloak-cloudfront-cdk/deploy.sh | 79 - .../keycloak-cloudfront-cdk/index.js | 103 - .../keycloak-cloudfront-cdk/package.json | 20 - .../keycloak-cloudfront-cdk/yarn.lock | 336 --- .../lambda-edge-example/babel.config.js | 33 - .../lambda-edge-example/index.js | 4 - .../lambda-edge-example/jest.config.js | 7 - .../lambda-edge-example/package.json | 44 - .../lambda-edge-example/src/Tentants.js | 58 - .../lambda-edge-example/src/index.js | 49 - .../lambda-edge-example/src/sessionKeys.js | 59 - .../webpack.config.babel.js | 50 - .../lambdaEdgeProxy.js | 87 - .../keycloak-cloudfront-portal/package.json | 70 - .../portal-realm.json | 1762 ------------- .../securityRealm1.json | 2317 ---------------- .../securityRealm2.json | 2329 ----------------- .../src/components/App.js | 95 - .../src/components/Header.js | 126 - .../keycloak-cloudfront-portal/src/index.js | 16 - .../keycloak-cloudfront-portal/tenant1.html | 10 - .../keycloak-cloudfront-portal/tenant2.html | 10 - .../webpack.config.babel.js | 114 - example/keycloak-cloudfront/README.md | 47 - example/keycloak-cloudfront/babel.config.js | 43 - example/keycloak-cloudfront/index.html | 10 - .../keycloak-cloudfront-cdk/cdk.json | 3 - .../keycloak-cloudfront-cdk/deploy.sh | 79 - .../keycloak-cloudfront-cdk/index.js | 103 - .../keycloak-cloudfront-cdk/package.json | 20 - .../lambda-edge-example/babel.config.js | 33 - .../lambda-edge-example/index.js | 4 - .../lambda-edge-example/jest.config.js | 7 - .../lambda-edge-example/package.json | 44 - .../lambda-edge-example/src/Tentants.js | 56 - .../lambda-edge-example/src/index.js | 71 - .../lambda-edge-example/src/sessionKeys.js | 59 - .../webpack.config.babel.js | 50 - .../keycloak-cloudfront/lambdaEdgeProxy.js | 87 - example/keycloak-cloudfront/package.json | 69 - .../keycloak-cloudfront/realm-tenant1.json | 1834 ------------- .../keycloak-cloudfront/realm-tenant2.json | 1851 ------------- .../keycloak-cloudfront/src/components/App.js | 87 - .../src/components/Header.js | 122 - example/keycloak-cloudfront/src/index.js | 16 - example/keycloak-cloudfront/tenant1.html | 10 - example/keycloak-cloudfront/tenant2.html | 10 - .../webpack.config.babel.js | 113 - keycloak-cloudfront-dynamodb/.npmignore | 16 - .../DynamoDbSessionStorage.js | 102 - keycloak-cloudfront-dynamodb/package.json | 26 - src/edge/lambdaEdgeUtils.js | 80 - src/edge/lamdaEdge.js | 35 - src/edge/router.js | 25 - src/edge/routes/Callback.js | 160 -- src/edge/routes/Logout.js | 60 - src/edge/routes/routes.js | 142 - src/edge/routes/utils/nonce.js | 19 - src/edge/routes/utils/redirectAuthServer.js | 189 -- src/edge/storage/SessionManager.js | 210 -- src/edge/storage/localSessionStorage.js | 94 - src/utils/CustomPageUtils.js | 72 - src/utils/TokenUtils.js | 35 - src/utils/cookiesUtils.js | 65 - src/utils/optionsUtils.js | 23 - 81 files changed, 4 insertions(+), 15777 deletions(-) delete mode 100644 __tests__/src/edge/lambdaEdgeUtilsTest.js delete mode 100644 __tests__/src/edge/lamdaEdgeTest.js delete mode 100644 __tests__/src/edge/routerTest.js delete mode 100644 __tests__/src/edge/routers/CallbackTest.js delete mode 100644 __tests__/src/edge/routers/LogoutTest.js delete mode 100644 __tests__/src/edge/routers/routesTest.js delete mode 100644 __tests__/src/edge/routers/utils/redirectAuthServerTest.js delete mode 100644 __tests__/src/edge/session/SessionManagerTest.js delete mode 100644 __tests__/src/edge/session/localSessionStorageTest.js delete mode 100644 __tests__/src/utils/cookiesUtilsTest.js delete mode 100644 example/keycloak-cloudfront-portal/README.md delete mode 100644 example/keycloak-cloudfront-portal/babel.config.js delete mode 100644 example/keycloak-cloudfront-portal/index.html delete mode 100644 example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/cdk.json delete mode 100755 example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/deploy.sh delete mode 100644 example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/index.js delete mode 100644 example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/package.json delete mode 100644 example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/yarn.lock delete mode 100644 example/keycloak-cloudfront-portal/lambda-edge-example/babel.config.js delete mode 100644 example/keycloak-cloudfront-portal/lambda-edge-example/index.js delete mode 100644 example/keycloak-cloudfront-portal/lambda-edge-example/jest.config.js delete mode 100644 example/keycloak-cloudfront-portal/lambda-edge-example/package.json delete mode 100644 example/keycloak-cloudfront-portal/lambda-edge-example/src/Tentants.js delete mode 100644 example/keycloak-cloudfront-portal/lambda-edge-example/src/index.js delete mode 100644 example/keycloak-cloudfront-portal/lambda-edge-example/src/sessionKeys.js delete mode 100644 example/keycloak-cloudfront-portal/lambda-edge-example/webpack.config.babel.js delete mode 100644 example/keycloak-cloudfront-portal/lambdaEdgeProxy.js delete mode 100644 example/keycloak-cloudfront-portal/package.json delete mode 100644 example/keycloak-cloudfront-portal/portal-realm.json delete mode 100644 example/keycloak-cloudfront-portal/securityRealm1.json delete mode 100644 example/keycloak-cloudfront-portal/securityRealm2.json delete mode 100644 example/keycloak-cloudfront-portal/src/components/App.js delete mode 100644 example/keycloak-cloudfront-portal/src/components/Header.js delete mode 100644 example/keycloak-cloudfront-portal/src/index.js delete mode 100644 example/keycloak-cloudfront-portal/tenant1.html delete mode 100644 example/keycloak-cloudfront-portal/tenant2.html delete mode 100644 example/keycloak-cloudfront-portal/webpack.config.babel.js delete mode 100644 example/keycloak-cloudfront/README.md delete mode 100644 example/keycloak-cloudfront/babel.config.js delete mode 100644 example/keycloak-cloudfront/index.html delete mode 100644 example/keycloak-cloudfront/keycloak-cloudfront-cdk/cdk.json delete mode 100755 example/keycloak-cloudfront/keycloak-cloudfront-cdk/deploy.sh delete mode 100644 example/keycloak-cloudfront/keycloak-cloudfront-cdk/index.js delete mode 100644 example/keycloak-cloudfront/keycloak-cloudfront-cdk/package.json delete mode 100644 example/keycloak-cloudfront/lambda-edge-example/babel.config.js delete mode 100644 example/keycloak-cloudfront/lambda-edge-example/index.js delete mode 100644 example/keycloak-cloudfront/lambda-edge-example/jest.config.js delete mode 100644 example/keycloak-cloudfront/lambda-edge-example/package.json delete mode 100644 example/keycloak-cloudfront/lambda-edge-example/src/Tentants.js delete mode 100644 example/keycloak-cloudfront/lambda-edge-example/src/index.js delete mode 100644 example/keycloak-cloudfront/lambda-edge-example/src/sessionKeys.js delete mode 100644 example/keycloak-cloudfront/lambda-edge-example/webpack.config.babel.js delete mode 100644 example/keycloak-cloudfront/lambdaEdgeProxy.js delete mode 100644 example/keycloak-cloudfront/package.json delete mode 100644 example/keycloak-cloudfront/realm-tenant1.json delete mode 100644 example/keycloak-cloudfront/realm-tenant2.json delete mode 100644 example/keycloak-cloudfront/src/components/App.js delete mode 100644 example/keycloak-cloudfront/src/components/Header.js delete mode 100644 example/keycloak-cloudfront/src/index.js delete mode 100644 example/keycloak-cloudfront/tenant1.html delete mode 100644 example/keycloak-cloudfront/tenant2.html delete mode 100644 example/keycloak-cloudfront/webpack.config.babel.js delete mode 100644 keycloak-cloudfront-dynamodb/.npmignore delete mode 100644 keycloak-cloudfront-dynamodb/DynamoDbSessionStorage.js delete mode 100644 keycloak-cloudfront-dynamodb/package.json delete mode 100644 src/edge/lambdaEdgeUtils.js delete mode 100644 src/edge/lamdaEdge.js delete mode 100644 src/edge/router.js delete mode 100644 src/edge/routes/Callback.js delete mode 100644 src/edge/routes/Logout.js delete mode 100644 src/edge/routes/routes.js delete mode 100644 src/edge/routes/utils/nonce.js delete mode 100644 src/edge/routes/utils/redirectAuthServer.js delete mode 100644 src/edge/storage/SessionManager.js delete mode 100644 src/edge/storage/localSessionStorage.js delete mode 100644 src/utils/CustomPageUtils.js delete mode 100644 src/utils/cookiesUtils.js diff --git a/README.md b/README.md index e57bada..b47c0f7 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ # Description Implementation [Keycloak](https://www.keycloak.org/) adapter for Cloud ## Features -- supports AWS API Gateway, AWS Cloudfront with Lambda@Edge +- supports AWS API Gateway - Resource based authorization ( [Keycloak Authorization Services](https://www.keycloak.org/docs/latest/authorization_services/) ) - works with non amazon services. - [Service to Service communication](./example/userToAdminAPI). @@ -18,9 +18,8 @@ Implementation [Keycloak](https://www.keycloak.org/) adapter for Cloud - supports "clientId/secret" and "client-jwt" credential types - Role based authorization - support MultiTenancy -- [cross-realm authentication](example/keycloak-cloudfront-portal) -- Regexp endpoints for Lambda@Edge - +- [cross-realm authentication](https://github.com/vzakharchenko/keycloak-api-gateway/tree/master/examples/crossTenantReactJSExample) +** Note: supporting Lambda@Edge moved to [https://github.com/vzakharchenko/keycloak-api-gateway](https://github.com/vzakharchenko/keycloak-api-gateway) ** # Installation ``` @@ -444,222 +443,7 @@ export function authorizer(event, context, callback) { } ``` -# Lambda:Edge -## 1. protect Url - -```javascript -import { lamdaEdge } from 'keycloak-lambda-authorizer'; -import { SessionManager } from 'keycloak-lambda-authorizer/src/edge/storage/SessionManager'; -import { LocalSessionStorage } from 'keycloak-lambda-authorizer/src/edge/storage/localSessionStorage'; -import { DynamoDbSessionStorage } from 'keycloak-lambda-authorizer/src/edge/storage/DynamoDbSessionStorage'; -import { isLocalhost } from 'keycloak-lambda-authorizer/src/edge/lambdaEdgeUtils'; - -const keycloakJson = ...; -const privateKey = ...; -const publicKey = ...; - -lamdaEdge.routes.addProtected( - '/', -keycloakJson, -{ - enforce: { - enabled: true, - resource: { - name: 'tenantResource', - }, - }, -} -); -// eslint-disable-next-line import/prefer-default-export -export async function authorization(event, context, callback) { - await lamdaEdge.lambdaEdgeRouter(event, context, new SessionManager(isLocalhost()? new LocalSessionStorage(): new DynamoDbSessionStorage({ region: 'us-east-1' },'teablename'), { - keys: { - privateKey, - publicKey, - }, - }), callback); -} -``` -## 2. protect Url with Regexp - -```javascript -import { lamdaEdge } from 'keycloak-lambda-authorizer'; -import { SessionManager } from 'keycloak-lambda-authorizer/src/edge/storage/SessionManager'; -import { LocalSessionStorage } from 'keycloak-lambda-authorizer/src/edge/storage/localSessionStorage'; -import { DynamoDbSessionStorage } from 'keycloak-lambda-authorizer/src/edge/storage/DynamoDbSessionStorage'; -import { isLocalhost } from 'keycloak-lambda-authorizer/src/edge/lambdaEdgeUtils'; - -const keycloakJson = ...; -const privateKey = ...; -const publicKey = ...; - -lamdaEdge.routes.addProtected( - (^)(\/|)someUrl(|((\/)))$, - keycloakJson, -{ - enforce: { - enabled: true, - resource: { - name: 'tenantResource', - }, - }, -} -); -// eslint-disable-next-line import/prefer-default-export -export async function authorization(event, context, callback) { - await lamdaEdge.lambdaEdgeRouter(event, context, new SessionManager(isLocalhost()? new LocalSessionStorage(): new DynamoDbSessionStorage({ region: 'us-east-1' },'teablename'), { - keys: { - privateKey, - publicKey, - }, - }), callback); -} -``` -## 3. protect Url with custom response handler - -```js -lamdaEdge.routes.addProtected( - '/', -keycloakJson, -{ - enforce: { - enabled: true, - resource: { - name: 'tenantResource', - }, - }, - responseHandler: async (request, options)=>{ - const jwtToken = request.token; - const uri = request.uri; - if (uri.startsWith('/callback') || - uri.startsWith('callback')) { - return callBackPageHandle; - } - } -} -); -``` -## 4. Create JWKS endpoint by Lambda:Edge - -```javascript -import { lamdaEdge } from 'keycloak-lambda-authorizer'; -import { SessionManager } from 'keycloak-lambda-authorizer/src/edge/storage/SessionManager'; -import { LocalSessionStorage } from 'keycloak-lambda-authorizer/src/edge/storage/localSessionStorage'; -import { DynamoDbSessionStorage } from 'keycloak-lambda-authorizer/src/edge/storage/DynamoDbSessionStorage'; -import { isLocalhost } from 'keycloak-lambda-authorizer/src/edge/lambdaEdgeUtils'; - -const privateKey = ...; -const publicKey = ...; - -lamdaEdge.routes.addJwksEndpoint('/cert', publicKey.key); - -// eslint-disable-next-line import/prefer-default-export -export async function authorization(event, context, callback) { - await lamdaEdge.lambdaEdgeRouter(event, context, new SessionManager(isLocalhost()? new LocalSessionStorage(): new DynamoDbSessionStorage({ region: 'us-east-1' },'teablename'), { - keys: { - privateKey, - publicKey, - }, - }), callback); -} -``` - - -## 5. Public url - -```javascript -import { lamdaEdge } from 'keycloak-lambda-authorizer'; -import { SessionManager } from 'keycloak-lambda-authorizer/src/edge/storage/SessionManager'; -import { LocalSessionStorage } from 'keycloak-lambda-authorizer/src/edge/storage/localSessionStorage'; -import { DynamoDbSessionStorage } from 'keycloak-cloudfront-dynamodb/DynamoDbSessionStorage'; -import { isLocalhost } from 'keycloak-lambda-authorizer/src/edge/lambdaEdgeUtils'; - -const privateKey = ...; -const publicKey = ...; - -lamdaEdge.routes.addUnProtected('/withoutAuthorization'); - -// eslint-disable-next-line import/prefer-default-export -export async function authorization(event, context, callback) { - await lamdaEdge.lambdaEdgeRouter(event, context, new SessionManager(isLocalhost()? new LocalSessionStorage(): new DynamoDbSessionStorage({ region: 'us-east-1' },'teablename'), { - keys: { - privateKey, - publicKey, - }, - }), callback); -} -``` - -## 6. Custom Url Handler - -```javascript -import { lamdaEdge } from 'keycloak-lambda-authorizer'; -import { SessionManager } from 'keycloak-lambda-authorizer/src/edge/storage/SessionManager'; -import { LocalSessionStorage } from 'keycloak-lambda-authorizer/src/edge/storage/localSessionStorage'; -import { DynamoDbSessionStorage } from 'keycloak-cloudfront-dynamodb/DynamoDbSessionStorage'; -import { isLocalhost } from 'keycloak-lambda-authorizer/src/edge/lambdaEdgeUtils'; - -const privateKey = ...; -const publicKey = ...; - -lamdaEdge.routes.addRoute({ - isRoute: async (request) => await isRequest(request, '/someUrl'), - handle: async (request, config, callback) => { - const response=... ; - YOUR LOGIC - callback(null, response); - }, - }); - -// eslint-disable-next-line import/prefer-default-export -export async function authorization(event, context, callback) { - await lamdaEdge.lambdaEdgeRouter(event, context, new SessionManager(isLocalhost()? new LocalSessionStorage(): new DynamoDbSessionStorage({ region: 'us-east-1' },'teablename'), { - keys: { - privateKey, - publicKey, - }, - }), callback); -} -``` - -## 7. Custom Url Handler with Lambda:Edge [EventType](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html) - - -```javascript -import { lamdaEdge } from 'keycloak-lambda-authorizer'; -import { SessionManager } from 'keycloak-lambda-authorizer/src/edge/storage/SessionManager'; -import { LocalSessionStorage } from 'keycloak-lambda-authorizer/src/edge/storage/localSessionStorage'; -import { DynamoDbSessionStorage } from 'keycloak-cloudfront-dynamodb/DynamoDbSessionStorage'; -import { isLocalhost } from 'keycloak-lambda-authorizer/src/edge/lambdaEdgeUtils'; - -const privateKey = ...; -const publicKey = ...; - -lamdaEdge.routes.addRoute({ - isRoute: async (request) => await isRequest(request, '/someUrl'), - handle: async (request, config, callback) => { - if (config.eventType === 'viewer-request') { // original-request, origin-response, viewer-request, viewer-response, local-request - const response=... ; - YOUR LOGIC - callback(null, response); - } else { - callback(null, request); - } - }, - }); - -// eslint-disable-next-line import/prefer-default-export -export async function authorization(event, context, callback) { - await lamdaEdge.lambdaEdgeRouter(event, context, new SessionManager(isLocalhost()? new LocalSessionStorage(): new DynamoDbSessionStorage({ region: 'us-east-1' },'teablename'), { - keys: { - privateKey, - publicKey, - }, - }), callback); -} -``` - -# 8. Implementation For Custom Service or non amazon cloud +# Implementation For Custom Service or non amazon cloud ```javascript import { adapter } from 'keycloak-lambda-authorizer'; @@ -698,160 +482,4 @@ async function handler(request,response) { } ``` -## 9. protect Url with keycloak function - -```javascript -import { lamdaEdge } from 'keycloak-lambda-authorizer'; -import { SessionManager } from 'keycloak-lambda-authorizer/src/edge/storage/SessionManager'; -import { LocalSessionStorage } from 'keycloak-lambda-authorizer/src/edge/storage/localSessionStorage'; -import { DynamoDbSessionStorage } from 'keycloak-lambda-authorizer/src/edge/storage/DynamoDbSessionStorage'; -import { isLocalhost } from 'keycloak-lambda-authorizer/src/edge/lambdaEdgeUtils'; - -const privateKey = ...; -const publicKey = ...; - -function getKeycloakJson(realm, clientId){ - return { - "realm": realm, - "auth-server-url": "http://localhost:8090/auth", - "ssl-required": "external", - "resource": clientId, - "verify-token-audience": true, - "credentials": { - "secret": "772decbe-0151-4b08-8171-bec6d097293b" - }, - "confidential-port": 0, - "policy-enforcer": {} -} -} - -lamdaEdge.routes.addProtected( - '/', -getKeycloakJson("lambda-authorizer", "lambda"), -{ - enforce: { - enabled: true, - resource: { - name: 'tenantResource', - }, - }, -} -); -// eslint-disable-next-line import/prefer-default-export -export async function authorization(event, context, callback) { - await lamdaEdge.lambdaEdgeRouter(event, context, new SessionManager(isLocalhost()? new LocalSessionStorage(): new DynamoDbSessionStorage({ region: 'us-east-1' },'teablename'), { - keys: { - privateKey, - publicKey, - }, - }), callback); -} -``` - -## 10. protect Url with Uma - -```javascript -lamdaEdge.routes.addProtected( - '/', -keycloakJson, -{ - enforce: { - enabled: true, - clientId: 'CLIENT_ID', - resource: { - name: 'tenantResource', - }, - }, -} -); -``` - -## 11. Modify Session - -```js -lamdaEdge.routes.addProtected( - '/', -keycloakJson, -{ - enforce: { - enabled: true, - resource: { - name: 'tenantResource', - }, - }, - sessionModify: (sessionToken, token, options) => { - const newSessionToken = { ...sessionToken }; - sessionToken.newProperty="test"; - return newSessionToken; - }, - sessionDelete: (sessionToken, token, options) => { - const newSessionToken = { ...sessionToken }; - delete sessionToken.newProperty; - return newSessionToken; - }, -} -); -``` -## 12. Support custom Idp(kc_idp_hint) - -```js -lamdaEdge.routes.addProtected( - '/', -keycloakJson, -{ - enforce: { - enabled: true, - resource: { - name: 'tenantResource', - }, - }, - kc_idp_hint:'tenantIdp' -} -); -``` - -## 13. Custom Router selector - -```js -lamdaEdge.routes.addProtected( - '/', -keycloakJson, -{ - enforce: { - enabled: true, - resource: { - name: 'tenantResource', - }, - }, - isRequest: (request, routePath, ret)=>{ - return true; - } -} -); - -``` -## 14. Resource Handler - -```js - const keycloakJSON = ...; // read Keycloak.json - apigateway.awsHandler(event, keycloakJSON, { - enforce: { - enabled: true, - resource: { - name: 'SOME_RESOURCE', - uri: 'RESOURCE_URI', - matchingUri: true, - }, - resourceHandler:(resourceJson, options)=>{ - console.log('resource: ' + JSON.stringify(resourceJson)); - } - }, - }).then((token)=>{ - // Success - }).catch((e)=>{ - // Failed - }); -} -``` - # If you find these useful, please [Donate](https://secure.wayforpay.com/button/b18610f33a01c)! diff --git a/__tests__/src/edge/lambdaEdgeUtilsTest.js b/__tests__/src/edge/lambdaEdgeUtilsTest.js deleted file mode 100644 index 2b82987..0000000 --- a/__tests__/src/edge/lambdaEdgeUtilsTest.js +++ /dev/null @@ -1,183 +0,0 @@ -jest.mock('../../../src/clientAuthorization'); -jest.mock('jsonwebtoken'); - -const jsonwebtoken = require('jsonwebtoken'); -const { clientJWT } = require('../../../src/clientAuthorization'); -const { - signState, - validateState, - tenantName, - updateResponse, - getHostUrl, -} = require('../../../src/edge/lambdaEdgeUtils'); - -describe('testing lambdaEdgeUtils', () => { - beforeEach(() => { - clientJWT.mockImplementation(async () => 'signature'); - jsonwebtoken.decode.mockImplementation(() => ({ - header: { alg: 'rs256' }, - })); - jsonwebtoken.verify.mockImplementation(() => ({ - n: 'undefined-undefined', - })); - }); - - afterEach(() => { - }); - - test('test signState', async () => { - const ret = await signState('/', { - logger: console, - keycloakJson: {}, - sessionManager: - { sessionOptions: { sessionOptions: {} } }, - }); - expect(ret).toEqual('signature'); - }); - - test('test validateState', async () => { - const ret = await validateState('Token', { - logger: console, - keycloakJson: {}, - sessionManager: { - sessionOptions: { keys: { publicKey: { key: 'PUBLIC_KEY' } } }, - }, - }); - expect(ret).toEqual({ n: 'undefined-undefined' }); - }); - - test('test validateState none', async () => { - jsonwebtoken.decode.mockImplementation(() => ({ - header: { alg: 'none' }, - })); - try { - await validateState('Token', { - logger: console, - keycloakJson: {}, - sessionManager: { - sessionOptions: { keys: { publicKey: { key: 'PUBLIC_KEY' } } }, - }, - }); - throw new Error('Unexpected state'); - } catch (e) { - expect(e.message).toEqual('invalid token'); - } - }); - - test('test validateState invalid token', async () => { - jsonwebtoken.decode.mockImplementation(() => ({ - })); - try { - await validateState('Token', { - logger: console, - keycloakJson: {}, - sessionManager: { - sessionOptions: { keys: { publicKey: { key: 'PUBLIC_KEY' } } }, - }, - }); - throw new Error('Unexpected state'); - } catch (e) { - expect(e.message).toEqual('invalid token (header part)'); - } - }); - - test('test validateState invalid token 3', async () => { - const newVar = await validateState(null, { - logger: console, - keycloakJson: {}, - sessionManager: { - sessionOptions: { keys: { publicKey: { key: 'PUBLIC_KEY' } } }, - }, - }); - expect(newVar).toEqual(null); - }); - - test('test validateState invalid token 2', async () => { - jsonwebtoken.decode.mockImplementation(() => null); - try { - await validateState('Token', { - logger: console, - keycloakJson: {}, - sessionManager: { - sessionOptions: { keys: { publicKey: { key: 'PUBLIC_KEY' } } }, - }, - }); - throw new Error('Unexpected state'); - } catch (e) { - expect(e.message).toEqual('invalid token (header part)'); - } - }); - - test('test validateState hs', async () => { - jsonwebtoken.decode.mockImplementation(() => ({ - header: { alg: 'hs64' }, - })); - try { - await validateState('Token', { - logger: console, - keycloakJson: {}, - sessionManager: { - sessionOptions: { keys: { publicKey: { key: 'PUBLIC_KEY' } } }, - }, - }); - throw new Error('Unexpected state'); - } catch (e) { - expect(e.message).toEqual('invalid token'); - } - }); - - test('test tenantName', async () => { - const tn = tenantName({ realm: 'name', resource: 'resource' }); - expect(tn).toEqual('name-resource'); - }); - - test('test getHostUrl', async () => { - const request = { headers: { referer: [{ value: 'https:/test.com' }] } }; - const url = getHostUrl(request); - expect(url).toEqual('https:/test.com'); - }); - - test('updateResponse test empty', async () => { - const request = {}; - const response = {}; - updateResponse(request, response); - expect(response).toEqual({}); - }); - - test('updateResponse test', async () => { - const request = {}; - const response = { - headers: { - 'set-cookie': [{ value: 'test' }], - }, - }; - updateResponse(request, response); - expect(response).toEqual({ - headers: { - 'set-cookie': [ - { - value: 'test', - }, - ], - }, - }); - }); - test('updateResponse test 2', async () => { - const request = { headers: { referer: [{ value: 'https:/test.com' }] } }; - const response = { - headers: { - 'set-cookie': [{ value: 'test' }], - }, - }; - updateResponse(request, response); - expect(response).toEqual({ - headers: { - 'set-cookie': [ - { - value: 'test; Domain=https:/test.com; Secure', - }, - ], - }, - }); - }); -}); diff --git a/__tests__/src/edge/lamdaEdgeTest.js b/__tests__/src/edge/lamdaEdgeTest.js deleted file mode 100644 index 9dd06d3..0000000 --- a/__tests__/src/edge/lamdaEdgeTest.js +++ /dev/null @@ -1,71 +0,0 @@ -jest.mock('../../../src/edge/router'); -jest.mock('../../../src/edge/lambdaEdgeUtils'); -const { getRoute } = require('../../../src/edge/router'); - -const { updateResponse } = require('../../../src/edge/lambdaEdgeUtils'); - -const lamdaEdge = require('../../../src/edge/lamdaEdge'); - -describe('testing lamdaEdge', () => { - beforeEach(() => { - getRoute.mockImplementation(async () => ({ handle: async (request, config, f) => { f(null, { response: 'test' }); } })); - updateResponse.mockImplementation((request, response) => response); - }); - - afterEach(() => { - }); - - test('test lambdaEdgeRouter', async () => { - await lamdaEdge.lambdaEdgeRouter({ - Records: [{ - cf: { request: {}, config: {} }, - }], - }, {}, {}, (error, response) => { - expect(response.response).toEqual('test'); - }); - }); - - test('test lambdaEdgeRouter without route', async () => { - getRoute.mockImplementation(() => null); - const event = { - Records: [{ - cf: { request: { test: {} }, config: {} }, - }], - }; - await lamdaEdge.lambdaEdgeRouter(event, {}, {}, (error, response) => { - expect(response).toEqual({ test: {} }); - }); - }); - - test('test lambdaEdgeRouter error', async () => { - await lamdaEdge.lambdaEdgeRouter({ - Records: [{ - cf: { request: {}, config: {} }, - }], - }, {}, { - sessionOptions: { - route: { - internalServerError: (request, callback) => { - callback(null, { response: 'error' }); - }, - }, - }, - }, (error, response) => { - expect(response.response).toEqual('error'); - }); - }); - test('test lambdaEdgeRouter error2', async () => { - getRoute.mockImplementation(async () => ({ handle: async () => { throw new Error('test'); } })); - await lamdaEdge.lambdaEdgeRouter({ Records: [] }, {}, { - sessionOptions: { - route: { - internalServerError: (request, callback) => { - callback(null, { response: 'error' }); - }, - }, - }, - }, (error, response) => { - expect(response.response).toEqual('error'); - }); - }); -}); diff --git a/__tests__/src/edge/routerTest.js b/__tests__/src/edge/routerTest.js deleted file mode 100644 index 1cef86b..0000000 --- a/__tests__/src/edge/routerTest.js +++ /dev/null @@ -1,25 +0,0 @@ -jest.mock('yallist'); -const yallist = require('yallist'); - -yallist.create.mockImplementation(() => ({ - toArray: () => [{ name: 'test', isRoute: () => true }], - push: () => { - }, - -})); -const router = require('../../../src/edge/router'); - -describe('testing edgeRouter', () => { - beforeEach(() => { - - }); - - afterEach(() => { - }); - - test('test registerRoute/getRouter', async () => { - router.registerRoute({}); - const route = await router.getRoute({}, {}); - expect(route.name).toEqual('test'); - }); -}); diff --git a/__tests__/src/edge/routers/CallbackTest.js b/__tests__/src/edge/routers/CallbackTest.js deleted file mode 100644 index 754f000..0000000 --- a/__tests__/src/edge/routers/CallbackTest.js +++ /dev/null @@ -1,203 +0,0 @@ -jest.mock('cookie'); - -jest.mock('querystring'); -jest.mock('../../../../src/edge/lambdaEdgeUtils'); -jest.mock('../../../../src/clientAuthorization'); -jest.mock('../../../../src/utils/TokenUtils'); -jest.mock('../../../../src/utils/cookiesUtils'); - -const qs = require('querystring'); -const lambdaEdgeUtils = require('../../../../src/edge/lambdaEdgeUtils'); -const clientAuthorization = require('../../../../src/clientAuthorization'); -const { unauthorized, internalServerError } = require('../../../../src/utils/CustomPageUtils'); -const { decodeAccessToken } = require('../../../../src/utils/TokenUtils'); -const cookiesUtils = require('../../../../src/utils/cookiesUtils'); -const { callbackHandler } = require('../../../../src/edge/routes/Callback'); - -const sessionManager = { - checkSession: async () => true, - updateSession: async () => true, - updateSessionToken: async () => 'SESSION_JWT', -}; - -describe('testing callback', () => { - beforeEach(() => { - qs.parse.mockImplementation(() => ({ code: 'CODE' })); - lambdaEdgeUtils.validateState.mockImplementation(() => ({ s: '/' })); - clientAuthorization.getTokenByCode.mockImplementation(async () => ({ refresh_token: 'REFRESH_TOKEN', access_token: 'ACCESS_TOKEN' })); - clientAuthorization.exchangeRPT.mockImplementation(async () => ({ refresh_token: 'REFRESH_TOKEN', access_token: 'ACCESS_TOKEN' })); - decodeAccessToken.mockImplementation(() => ({ accessToken: 'TOKEN', accessTokenDecode: { email: 'test@test', tenants: { test: { resNew: {} } } } })); - cookiesUtils.getCookie.mockImplementation(() => ({ - session: 's', - sessionToken: 'Session_TOKEN', - })); - }); - - afterEach(() => { - }); - - test('test callback Error', async () => { - qs.parse.mockImplementation(() => ({ error: 'access_denied' })); - await callbackHandler({ headers: [] }, { - logger: console, - route: { unauthorized }, - }, (error, response) => { - expect(response).toEqual({ - body: "\n \n \n \n \n \n We've got some trouble | 401 - Unauthorized\n \n \n \n

Access Denied Error 401

\n \n \n \n ", - status: '401', - statusDescription: 'Unauthorized', - }); - }); - }); - - test('test callback empty code', async () => { - qs.parse.mockImplementation(() => ({ code: '' })); - await callbackHandler({ headers: [] }, { - logger: console, - route: { unauthorized }, - }, (error, response) => { - expect(response).toEqual({ - body: "\n \n \n \n \n \n We've got some trouble | 401 - Unauthorized\n \n \n \n

No Code Found Error 401

\n \n \n \n ", - status: '401', - statusDescription: 'Unauthorized', - }); - }); - }); - - test('test callback invalid state ', async () => { - lambdaEdgeUtils.validateState.mockImplementation(() => null); - await callbackHandler({ headers: [] }, { - logger: console, - keycloakJson: () => ({ realm: 'test', resource: 'res' }), - route: { unauthorized, internalServerError }, - }, (error, response) => { - expect(response).toEqual({ - body: "\n \n \n \n \n \n We've got some trouble | 500 - Internal Server Error\n \n \n \n

Internal Server Error Error 500

\n \n \n \n ", - status: '500', - statusDescription: 'Internal Server Error', - }); - }); - }); - - test('test Internal Error ', async () => { - clientAuthorization.getTokenByCode.mockImplementation(() => { throw new Error('Test Error'); }); - await callbackHandler({ headers: [] }, { - logger: console, - keycloakJson: () => ({ realm: 'test', resource: 'res' }), - route: { unauthorized, internalServerError }, - }, (error, response) => { - expect(response).toEqual({ - body: "\n \n \n \n \n \n We've got some trouble | 500 - Internal Server Error\n \n \n \n

Internal Server Error Error 500

\n \n \n \n ", - status: '500', - statusDescription: 'Internal Server Error', - }); - }); - }); - - test('test Success RPT ', async () => { - await callbackHandler({ headers: [] }, { - logger: console, - sessionManager, - enforce: { enabled: true }, - keycloakJson: () => ({ realm: 'test', resource: 'res' }), - route: { unauthorized, internalServerError }, - }, (error, response) => { - expect(response).toEqual({ - status: '302', - statusDescription: 'Found', - body: 'ID token retrieved.', - headers: { - location: [ - { - key: 'Location', - value: '/', - }, - ], - 'set-cookie': [ - { - key: 'Set-Cookie', - }, - { - key: 'Set-Cookie', - }, - { - key: 'Set-Cookie', - }, - ], - }, - }); - }); - }); - - test('test Success Logout ', async () => { - decodeAccessToken.mockImplementation(() => ({ accessToken: 'TOKEN', accessTokenDecode: { email: 'test@test', tenants: { test: { res: { session_state: 'state' } } } } })); - - await callbackHandler({ headers: [] }, { - logger: console, - sessionManager, - enforce: { enabled: true }, - keycloakJson: () => ({ realm: 'test', resource: 'res' }), - route: { unauthorized, internalServerError }, - }, (error, response) => { - expect(response).toEqual({ - body: 'ID token retrieved.', - headers: { - location: [ - { - key: 'Location', - value: '/test/res/logout', - }, - ], - 'set-cookie': [ - { - key: 'Set-Cookie', - }, - { - key: 'Set-Cookie', - }, - { - key: 'Set-Cookie', - }, - ], - }, - status: '302', - statusDescription: 'Found', - }); - }); - }); - - test('test Success ', async () => { - await callbackHandler({ headers: [] }, { - logger: console, - sessionManager, - enforce: {}, - keycloakJson: () => ({ realm: 'test', resource: 'res' }), - route: { unauthorized, internalServerError }, - }, (error, response) => { - expect(response).toEqual({ - status: '302', - statusDescription: 'Found', - body: 'ID token retrieved.', - headers: { - location: [ - { - key: 'Location', - value: '/', - }, - ], - 'set-cookie': [ - { - key: 'Set-Cookie', - }, - { - key: 'Set-Cookie', - }, - { - key: 'Set-Cookie', - }, - ], - }, - }); - }); - }); -}); diff --git a/__tests__/src/edge/routers/LogoutTest.js b/__tests__/src/edge/routers/LogoutTest.js deleted file mode 100644 index 3d2853a..0000000 --- a/__tests__/src/edge/routers/LogoutTest.js +++ /dev/null @@ -1,62 +0,0 @@ -jest.mock('cookie'); -jest.mock('querystring'); -jest.mock('../../../../src/edge/lambdaEdgeUtils'); -jest.mock('../../../../src/utils/restCalls'); -jest.mock('../../../../src/utils/TokenUtils'); -jest.mock('../../../../src/utils/cookiesUtils'); - -const qs = require('querystring'); -const { tenantLogout } = require('../../../../src/edge/routes/Logout'); -const cookiesUtils = require('../../../../src/utils/cookiesUtils'); -const { decodeAccessToken } = require('../../../../src/utils/TokenUtils'); - -const sessionManager = { - checkSession: async () => true, - deleteTenantSession: async () => ({}), - updateSessionToken: async () => 'SESSION_JWT', -}; - -describe('testing logout', () => { - beforeEach(() => { - qs.parse.mockImplementation(() => ({ url: '/url' })); - decodeAccessToken.mockImplementation(() => ({ accessToken: 'TOKEN', accessTokenDecode: { email: 'test@test', exp: 1000 } })); - cookiesUtils.getCookie.mockImplementation(() => ({ - session: 's', - sessionToken: 'Session_TOKEN', - })); - }); - - afterEach(() => { - }); - - test('test tenantLogout', async () => { - const ret = await tenantLogout({}, { - sessionManager, - keycloakJson: () => ({ realm: 'name', resource: 'resource' }), - }); - expect(ret).toEqual({ - body: 'Redirect to logout page', - headers: { - location: [ - { - key: 'Location', - value: 'undefined/realms/name/protocol/openid-connect/logout?redirect_uri=/url', - }, - ], - 'set-cookie': [ - { - key: 'Set-Cookie', - }, - { - key: 'Set-Cookie', - }, - { - key: 'Set-Cookie', - }, - ], - }, - status: '302', - statusDescription: 'Found', - }); - }); -}); diff --git a/__tests__/src/edge/routers/routesTest.js b/__tests__/src/edge/routers/routesTest.js deleted file mode 100644 index d9bfdad..0000000 --- a/__tests__/src/edge/routers/routesTest.js +++ /dev/null @@ -1,186 +0,0 @@ -jest.mock('../../../../src/edge/router'); -jest.mock('../../../../src/adapter/adapter'); -jest.mock('../../../../src/edge/routes/Logout'); -jest.mock('../../../../src/edge/routes/Callback'); -jest.mock('../../../../src/edge/routes/utils/redirectAuthServer'); -const { registerRoute } = require('../../../../src/edge/router'); -const { jwksUrl } = require('../../../../src/adapter/adapter'); -const routes = require('../../../../src/edge/routes/routes'); -const { tenantLogout } = require('../../../../src/edge/routes/Logout'); -const { callbackHandler } = require('../../../../src/edge/routes/Callback'); -const { checkToken, refreshResponse } = require('../../../../src/edge/routes/utils/redirectAuthServer'); - -const routers = { -}; - -describe('testing routers', () => { - beforeEach(() => { - registerRoute.mockImplementation(() => {}); - jwksUrl.mockImplementation(() => 'jwks response'); - tenantLogout.mockImplementation(async () => ({ - status: '302', - statusDescription: 'Found', - })); - - callbackHandler.mockImplementation(async () => ({ - status: '302', - statusDescription: 'Found', - })); - checkToken.mockImplementation(async () => ({ - status: '302', - statusDescription: 'Found', - })); - refreshResponse.mockImplementation((r) => r); - }); - - afterEach(() => { - }); - - test('test addRoute', () => { - routes.addRoute({}); - }); - test('test isRequest', async () => { - expect(await routes.isRequest({ uri: 't' }, 't')).toEqual(true); - expect(await routes.isRequest({ uri: 't' }, 'f')).toEqual(false); - expect(await routes.isRequest({ uri: 't' }, 'f', () => true)).toEqual(true); - }); - - test('test unProtected', async () => { - routers.unProtected = []; - registerRoute.mockImplementation((route) => { - routers.unProtected.push(route); - }); - routes.addUnProtected('/test'); - const route = routers.unProtected[0]; - expect(await route.isRoute({ uri: '/t' })).toEqual(false); - expect(await route.isRoute({ uri: '/test' })).toEqual(true); - await route.handle({}, {}, (error, response) => { - expect(response).toEqual({}); - }); - }); - - test('test unProtected Regexp', async () => { - routers.unProtected = []; - registerRoute.mockImplementation((route) => { - routers.unProtected.push(route); - }); - routes.addUnProtected(new RegExp('(^)(\\/)(test)(/$|(\\?|$))', 'g')); - const route = routers.unProtected[0]; - expect(await route.isRoute({ uri: '/t' })).toEqual(false); - expect(await route.isRoute({ uri: '/test' })).toEqual(true); - expect(await route.isRoute({ uri: '/test/' })).toEqual(true); - expect(await route.isRoute({ uri: '/test/fdfd' })).toEqual(false); - expect(await route.isRoute({ uri: '/test?test=kk' })).toEqual(true); - await route.handle({}, {}, (error, response) => { - expect(response).toEqual({}); - }); - }); - - test('test JWKS', async () => { - routers.jwks = []; - registerRoute.mockImplementation((route) => { - routers.jwks.push(route); - }); - routes.addJwksEndpoint('/test', 'publicKey'); - const route = routers.jwks[0]; - expect(await route.isRoute({ uri: '/test' })).toEqual(true); - await route.handle({}, {}, (error, response) => { - expect(response).toEqual({ - body: 'jwks response', - status: '200', - }); - }); - }); - - test('test Protected keycloak JSON', async () => { - routers.protected = []; - registerRoute.mockImplementation((route) => { - routers.protected.push(route); - }); - routes.addProtected('/', () => ({ realm: 'realm', resource: 'resource' })); - const routeLogout = routers.protected[0]; - expect(await routeLogout.isRoute({ uri: '/realm/resource/logout' })).toEqual(true); - await routeLogout.handle({}, {}, (error, response) => { - expect(response).toEqual({ - status: '302', - statusDescription: 'Found', - }); - }); - - const routeCallback = routers.protected[1]; - expect(await routeCallback.isRoute({ uri: '/realm/resource/callback' })).toEqual(true); - await routeCallback.handle({}, {}, (error, response) => { - expect(response).toEqual({ - status: '302', - statusDescription: 'Found', - }); - }); - - const routeRefresh = routers.protected[2]; - expect(await routeRefresh.isRoute({ uri: '/realm/resource/refresh' })).toEqual(true); - await routeRefresh.handle({}, {}, (error, response) => { - expect(response).toEqual({ - status: '302', - statusDescription: 'Found', - }); - }); - const route = routers.protected[3]; - expect(await route.isRoute({ uri: '/' })).toEqual(true); - expect(await route.isRoute({ uri: '/test' })).toEqual(true); - expect(await route.isRoute({ uri: '/test/333' })).toEqual(true); - await route.handle({ r: 'r' }, {}, (error, response) => { - expect(response).toEqual({ r: 'r' }); - }); - }); - - test('test Protected Error', () => { - try { - routes.addProtected('/'); - } catch (e) { - expect(e.message).toEqual('keycloak.json is empty'); - return; - } - throw new Error('Unexpeted state'); - }); - - test('test Protected', async () => { - routers.protected = []; - registerRoute.mockImplementation((route) => { - routers.protected.push(route); - }); - routes.addProtected('/', { realm: 'realm', resource: 'resource' }); - const routeLogout = routers.protected[0]; - expect(await routeLogout.isRoute({ uri: '/realm/resource/logout' })).toEqual(true); - await routeLogout.handle({}, {}, (error, response) => { - expect(response).toEqual({ - status: '302', - statusDescription: 'Found', - }); - }); - - const routeCallback = routers.protected[1]; - expect(await routeCallback.isRoute({ uri: '/realm/resource/callback' })).toEqual(true); - await routeCallback.handle({}, {}, (error, response) => { - expect(response).toEqual({ - status: '302', - statusDescription: 'Found', - }); - }); - - const routeRefresh = routers.protected[2]; - expect(await routeRefresh.isRoute({ uri: '/realm/resource/refresh' })).toEqual(true); - await routeRefresh.handle({}, {}, (error, response) => { - expect(response).toEqual({ - status: '302', - statusDescription: 'Found', - }); - }); - const route = routers.protected[3]; - expect(await route.isRoute({ uri: '/' })).toEqual(true); - expect(await route.isRoute({ uri: '/test' })).toEqual(true); - expect(await route.isRoute({ uri: '/test/333' })).toEqual(true); - await route.handle({ r: 'r' }, {}, (error, response) => { - expect(response).toEqual({ r: 'r' }); - }); - }); -}); diff --git a/__tests__/src/edge/routers/utils/redirectAuthServerTest.js b/__tests__/src/edge/routers/utils/redirectAuthServerTest.js deleted file mode 100644 index da6e87e..0000000 --- a/__tests__/src/edge/routers/utils/redirectAuthServerTest.js +++ /dev/null @@ -1,276 +0,0 @@ -jest.mock('../../../../../src/utils/TokenUtils'); -jest.mock('../../../../../src/edge/lambdaEdgeUtils'); -jest.mock('../../../../../src/utils/cookiesUtils'); -jest.mock('../../../../../src/utils/restCalls'); -const { decodeAccessToken, getActiveToken } = require('../../../../../src/utils/TokenUtils'); -const redirectAuthServer = require('../../../../../src/edge/routes/utils/redirectAuthServer'); -const cookiesUtils = require('../../../../../src/utils/cookiesUtils'); -const { unauthorized } = require('../../../../../src/utils/CustomPageUtils'); - -const sessionManager = { - checkSession: async () => true, - updateSessionToken: async () => 'SESSION_JWT', -}; - -describe('testing redirectAuthServer', () => { - beforeEach(() => { - decodeAccessToken.mockImplementation(() => ({ accessToken: 'TOKEN', accessTokenDecode: { email: 'test@test', tenants: { testRealm: { resource: {} } } } })); - getActiveToken.mockImplementation(async () => ({ accessToken: 'TOKEN', accessTokenDecode: { email: 'test@test' } })); - cookiesUtils.getCookie.mockImplementation(() => ({ - session: 's', - sessionToken: 'Session_TOKEN', - })); - }); - - afterEach(() => { - }); - - test('test refreshResponse', async () => { - const refreshResponse = redirectAuthServer.refreshResponse({ - acess_token: 'token', - isChanged: true, - }, 'refreshToken', { - keycloakJson: () => ({ - realm: 'testRealm', - resource: 'resource', - }), - }); - expect(refreshResponse) - .toEqual({ - headers: { - 'set-cookie': [ - { - key: 'Set-Cookie', - value: 'KEYCLOAK_AWS_undefined_EXPIRE=undefined; Path=/; Expires=Invalid Date', - }, - { - key: 'Set-Cookie', - value: 'KEYCLOAK_AWS_undefined=undefined; Path=/; Expires=Invalid Date', - }, - ], - }, - status: '200', - statusDescription: 'OK', - }); - }); - - test('test refreshResponse false', async () => { - const refreshResponse = redirectAuthServer.refreshResponse({ - acess_token: 'token', - isChanged: false, - }, 'refreshToken', { - keycloakJson: () => ({ - realm: 'testRealm', - resource: 'resource', - }), - }); - expect(refreshResponse) - .toEqual({ - headers: { - 'set-cookie': [ - { - key: 'Set-Cookie', - value: 'KEYCLOAK_AWS_undefined_EXPIRE=undefined; Path=/; Expires=Invalid Date', - }, - ], - }, - status: '200', - statusDescription: 'OK', - }); - }); - test('test refreshResponse without refreshToken', async () => { - const refreshResponse = redirectAuthServer.refreshResponse('token', null, { keycloakJson: () => ({ realm: 'testRealm', resource: 'resource' }) }); - expect(refreshResponse).toEqual({ - status: '200', - statusDescription: 'OK', - }); - }); - - test('test checkToken without cookie', async () => { - cookiesUtils.getCookie.mockImplementation(() => null); - const resp = await redirectAuthServer.checkToken((error, response) => { - expect(response).toEqual({ - status: '302', - statusDescription: 'Found', - body: 'Redirecting to OIDC provider', - }); - }, { - keycloakJson: () => ({ realm: 'testRealm', resource: 'resource' }), - request: {}, - logger: console, - }); - expect(resp).toEqual(null); - }); - - test('test checkToken Invalid Session', async () => { - const resp = await redirectAuthServer.checkToken((error, response) => { - expect(response).toEqual({ - status: '302', - statusDescription: 'Found', - body: 'Redirecting to OIDC provider', - }); - }, { - keycloakJson: () => ({ realm: 'testRealm', resource: 'resource' }), - request: {}, - sessionManager: { - checkSession: async () => false, - }, - logger: console, - }); - expect(resp).toEqual(null); - }); - - test('test checkToken expired token', async () => { - getActiveToken.mockImplementation(async () => null); - const resp = await redirectAuthServer.checkToken((error, response) => { - expect(response).toEqual({ - status: '302', - statusDescription: 'Found', - body: 'Redirecting to OIDC provider', - }); - }, { - keycloakJson: () => ({ realm: 'testRealm', resource: 'resource' }), - request: {}, - sessionManager, - logger: console, - }); - expect(resp).toEqual(null); - }); - test('test checkToken error', async () => { - getActiveToken.mockImplementation(async () => { - throw new Error('test'); - }); - const resp = await redirectAuthServer.checkToken((error, response) => { - expect(response).toEqual({ - body: "\n \n \n \n \n \n We've got some trouble | 401 - Unauthorized\n \n \n \n

test Error 401

Error: test

/

\n \n \n \n ", - status: '401', - statusDescription: 'Unauthorized', - }); - }, { - keycloakJson: () => ({ realm: 'testRealm', resource: 'resource' }), - request: {}, - sessionManager, - route: { unauthorized }, - logger: console, - }); - expect(resp).toEqual(null); - }); - - test('test checkToken redirect error', async () => { - decodeAccessToken.mockImplementation(() => ({ accessToken: 'TOKEN', accessTokenDecode: { email: 'test@test', tenants: { testRealm: { } } } })); - const resp = await redirectAuthServer.checkToken((error, response) => { - expect(response).toEqual({ - body: 'Redirecting to OIDC provider', - status: '302', - statusDescription: 'Found', - }); - }, { - keycloakJson: () => ({ realm: 'testRealm', resource: 'resource' }), - request: {}, - sessionManager, - route: { unauthorized }, - logger: console, - }); - expect(resp).toEqual(null); - }); - - test('test checkToken redirect error Realm', async () => { - decodeAccessToken.mockImplementation(() => ({ accessToken: 'TOKEN', accessTokenDecode: { email: 'test@test', tenants: { } } })); - const resp = await redirectAuthServer.checkToken((error, response) => { - expect(response).toEqual({ - body: 'Redirecting to OIDC provider', - status: '302', - statusDescription: 'Found', - }); - }, { - keycloakJson: () => ({ realm: 'testRealm', resource: 'resource' }), - request: {}, - sessionManager, - route: { unauthorized }, - logger: console, - }); - expect(resp).toEqual(null); - }); - - test('test checkToken redirect error Tenants', async () => { - decodeAccessToken.mockImplementation(() => ({ accessToken: 'TOKEN', accessTokenDecode: { email: 'test@test' } })); - const resp = await redirectAuthServer.checkToken((error, response) => { - expect(response).toEqual({ - body: 'Redirecting to OIDC provider', - status: '302', - statusDescription: 'Found', - }); - }, { - keycloakJson: () => ({ realm: 'testRealm', resource: 'resource' }), - request: {}, - sessionManager, - route: { unauthorized }, - logger: console, - }); - expect(resp).toEqual(null); - }); - - test('test checkToken', async () => { - await redirectAuthServer.checkToken(() => { - throw new Error('unexpected state'); - }, { - keycloakJson: () => ({ realm: 'testRealm', resource: 'resource' }), - sessionManager, - logger: console, - }); - }); - - test('test redirectToKeycloak', async () => { - await redirectAuthServer.redirectToKeycloak({}, { - keycloakJson: () => ({ realm: 'testRealm', resource: 'resource' }), - sessionManager, - logger: console, - }, 'ttt', (error, resp) => { - expect(resp).toEqual({ - body: 'Redirecting to OIDC provider', - status: '302', - statusDescription: 'Found', - }); - }); - }); - - test('test redirectToKeycloak idp', async () => { - await redirectAuthServer.redirectToKeycloak({}, { - kc_idp_hint: 'idp', - keycloakJson: () => ({ realm: 'testRealm', resource: 'resource' }), - sessionManager, - logger: console, - }, 'ttt', (error, resp) => { - expect(resp).toEqual({ - body: 'Redirecting to OIDC provider', - status: '302', - statusDescription: 'Found', - }); - }); - }); - - test('test redirectToKeycloak2', async () => { - await redirectAuthServer.redirectToKeycloak({ uri: '/manufacturer/test', querystring: 'redirectUri=/' }, { - keycloakJson: () => ({ realm: 'testRealm', resource: 'resource' }), - sessionManager, - logger: console, - }, null, (error, resp) => { - expect(resp).toEqual({ - body: 'Redirecting to OIDC provider', - status: '302', - statusDescription: 'Found', - }); - }); - }); - - test('test responseWithKeycloakRedirectToLoginPage', async () => { - await redirectAuthServer.responseWithKeycloakRedirectToLoginPage({}, { - keycloakJson: () => ({ realm: 'testRealm', resource: 'resource' }), - sessionManager, - request: {}, - logger: console, - }, null, (error, response) => { - expect(response); - }); - }); -}); diff --git a/__tests__/src/edge/session/SessionManagerTest.js b/__tests__/src/edge/session/SessionManagerTest.js deleted file mode 100644 index b4ee547..0000000 --- a/__tests__/src/edge/session/SessionManagerTest.js +++ /dev/null @@ -1,146 +0,0 @@ -jest.mock('jsonwebtoken'); -jest.mock('../../../../src/clientAuthorization'); -const jsonwebtoken = require('jsonwebtoken'); - -const { SessionManager } = require('../../../../src/edge/storage/SessionManager'); -const { clientJWT } = require('../../../../src/clientAuthorization'); - -const sessionStorage = { - saveSession: async () => { - - }, - updateSession: async () => { - - }, - getSessionIfExists: async () => 'test', - deleteSession: async () => { - - }, -}; - -describe('testing SessionManager', () => { - beforeEach(() => { - jsonwebtoken.decode.mockImplementation(() => ({ - header: { alg: 'rs256' }, - })); - jsonwebtoken.verify.mockImplementation(() => ({ - n: 'undefined-undefined', - })); - clientJWT.mockImplementation(async () => 'SESSION_TOKEN'); - }); - - afterEach(() => { - }); - - test('test sessionStorage', () => { - const session = new SessionManager(sessionStorage); - expect(session.sessionStorage).toEqual(sessionStorage); - }); - - test('test checkSession', async () => { - const session = new SessionManager(sessionStorage, { keys: { publicKey: { key: 'PUBLIC_KEY' } } }); - expect(await session.checkSession('TOKEN')).toEqual({ - n: 'undefined-undefined', - }); - }); - - test('test checkSession Failed', async () => { - jsonwebtoken.decode.mockImplementation(() => ({ - header: { alg: 'none' }, - })); - const session = new SessionManager(sessionStorage, { keys: { publicKey: { key: 'PUBLIC_KEY' } } }); - expect(await session.checkSession(null)).toEqual(null); - try { - expect(await session.checkSession('TOKEN')).toEqual(null); - } catch (e) { - expect(e.message).toEqual('invalid token'); - } - }); - - test('test checkSession Failed 2', async () => { - jsonwebtoken.decode.mockImplementation(() => ({ - header: { alg: 'hs256' }, - })); - const session = new SessionManager(sessionStorage, { keys: { publicKey: { key: 'PUBLIC_KEY' } } }); - try { - expect(await session.checkSession('TOKEN')).toEqual(null); - } catch (e) { - expect(e.message).toEqual('invalid token'); - } - }); - - test('test sessionOptions ', async () => { - const session = new SessionManager(sessionStorage, { keys: { publicKey: { key: 'PUBLIC_KEY' } } }); - expect(session.sessionOptions).toEqual({ keys: { publicKey: { key: 'PUBLIC_KEY' } } }); - }); - - test('test getSessionIfExists ', async () => { - const session = new SessionManager(sessionStorage, { keys: { publicKey: { key: 'PUBLIC_KEY' } } }); - jsonwebtoken.decode.mockImplementation(() => ({ - jti: 'testId', - })); - expect(await session.getSessionIfExists('TEDT')).toEqual('test'); - }); - - test('test updateSession ', async () => { - const session = new SessionManager(sessionStorage, { keys: { publicKey: { key: 'PUBLIC_KEY' } } }); - jsonwebtoken.decode.mockImplementation(() => ({ - jti: 'testId', - })); - expect(await session.updateSession('TEDT', 'tenant', {})).toEqual(undefined); - }); - - test('test updateSession custom handler', async () => { - const session = new SessionManager(sessionStorage, { keys: { publicKey: { key: 'PUBLIC_KEY' } }, sessionModify: (token) => token }); - jsonwebtoken.decode.mockImplementation(() => ({ - jti: 'testId', - })); - expect(await session.updateSession('TEDT', 'tenant', {})).toEqual(undefined); - }); - - test('test updateSessionToken ', async () => { - const session = new SessionManager(sessionStorage, { - keycloakJson: () => ({}), - keys: { publicKey: { key: 'PUBLIC_KEY' } }, - }); - jsonwebtoken.decode.mockImplementation(() => ({ - jti: 'testId', - })); - expect(await session.updateSessionToken('TEDT', 'tenant', {})).toEqual('SESSION_TOKEN'); - }); - - test('test updateSessionToken custom session handler', async () => { - const session = new SessionManager(sessionStorage, { - keycloakJson: () => ({}), - keys: { publicKey: { key: 'PUBLIC_KEY' } }, - sessionModify: (token) => token, - }); - jsonwebtoken.decode.mockImplementation(() => ({ - jti: 'testId', - })); - expect(await session.updateSessionToken('TEDT', 'tenant', {})).toEqual('SESSION_TOKEN'); - }); - - test('test deleteSession custom session handler', async () => { - const session = new SessionManager(sessionStorage, { - keycloakJson: {}, - keys: { publicKey: { key: 'PUBLIC_KEY' } }, - sessionDelete: (token) => token, - }); - jsonwebtoken.decode.mockImplementation(() => ({ - jti: 'testId', - })); - expect(await session.deleteSession('TEDT')).toEqual(undefined); - }); - - test('test createSession ', async () => { - const session = new SessionManager(sessionStorage, { - keycloakJson: () => ({}), - keys: { publicKey: { key: 'PUBLIC_KEY' } }, - }); - jsonwebtoken.decode.mockImplementation(() => ({ - jti: 'testId', - })); - expect(await session.createSession('host', 3, 'token', { keycloakJson: () => {} })).toEqual('SESSION_TOKEN'); - }); -}); diff --git a/__tests__/src/edge/session/localSessionStorageTest.js b/__tests__/src/edge/session/localSessionStorageTest.js deleted file mode 100644 index 5a04e05..0000000 --- a/__tests__/src/edge/session/localSessionStorageTest.js +++ /dev/null @@ -1,27 +0,0 @@ -jest.mock('fs'); -const { LocalSessionStorage } = require('../../../../src/edge/storage/localSessionStorage'); - -const storage = new LocalSessionStorage(); - -describe('testing localSessionStorageTest', () => { - beforeEach(() => { - - }); - - afterEach(() => { - }); - - test('test saveSession', async () => { - await storage.saveSession('sessionId'); - }); - - test('test updateSession', async () => { - await storage.updateSession('sessionId', 'tenant', 'token'); - }); - test('test getSessionIfExists ', async () => { - await storage.getSessionIfExists('sessionId'); - }); - test('test deleteSession ', async () => { - await storage.deleteSession('sessionId'); - }); -}); diff --git a/__tests__/src/utils/TokenUtilsTest.js b/__tests__/src/utils/TokenUtilsTest.js index 5327e67..1027050 100644 --- a/__tests__/src/utils/TokenUtilsTest.js +++ b/__tests__/src/utils/TokenUtilsTest.js @@ -1,7 +1,6 @@ jest.mock('jsonwebtoken'); jest.mock('../../../src/adapter/adapter'); jest.mock('../../../src/clientAuthorization'); -jest.mock('../../../src/edge/lambdaEdgeUtils'); const jwt = require('jsonwebtoken'); const tokenUtils = require('../../../src/utils/TokenUtils'); @@ -52,63 +51,4 @@ describe('testing TokenUtils', () => { const t = await tokenUtils.tokenIsValid({ access_token: 'TOKEN' }, {}); expect(t).toEqual(false); }); - - test('test tokenIsValid still active', async () => { - lambdaAdapter.mockImplementation(async () => {}); - const t = await tokenUtils.getActiveToken('SESSION', { access_token: 'TOKEN' }, {}); - expect(t).toEqual({ access_token: 'TOKEN' }); - }); - - test('test tokenIsValid not active and session expired', async () => { - lambdaAdapter.mockImplementation(async () => { throw new Error(); }); - const t = await tokenUtils.getActiveToken('SESSION', { access_token: 'TOKEN' }, - { - logger: console, - sessionManager: { - getSessionIfExists: async () => null, - }, - }); - expect(t).toEqual(null); - }); - - test('test tokenIsValid not active, refresh token expired', async () => { - lambdaAdapter.mockImplementation(async () => { throw new Error(); }); - keycloakRefreshToken.mockImplementation(async () => null); - const t = await tokenUtils.getActiveToken('SESSION', { access_token: 'TOKEN' }, - { - logger: console, - sessionManager, - keycloakJson: () => {}, - }); - expect(t).toEqual(null); - }); - - test('test tokenIsValid not active, error', async () => { - lambdaAdapter.mockImplementation(async () => { throw new Error(); }); - keycloakRefreshToken.mockImplementation(async () => { - throw new Error('test'); - }); - try { - await tokenUtils.getActiveToken('SESSION', { access_token: 'TOKEN' }, - { - logger: console, - sessionManager, - keycloakJson: () => {}, - }); - throw new Error('Unexpected state'); - } catch (e) { - expect(e.message).toEqual('Error: test'); - } - }); - - test('test tokenIsValid not active', async () => { - lambdaAdapter.mockImplementation(async () => { throw new Error(); }); - const t = await tokenUtils.getActiveToken('SESSION', { access_token: 'TOKEN' }, - { - logger: console, - sessionManager, - keycloakJson: () => {}, - }); - expect(t).toEqual('TOKEN'); - }); }); diff --git a/__tests__/src/utils/cookiesUtilsTest.js b/__tests__/src/utils/cookiesUtilsTest.js deleted file mode 100644 index 78eccdb..0000000 --- a/__tests__/src/utils/cookiesUtilsTest.js +++ /dev/null @@ -1,89 +0,0 @@ -jest.mock('cookie'); -jest.mock('../../../src/edge/lambdaEdgeUtils'); - -const cookie = require('cookie'); -const cookiesUtils = require('../../../src/utils/cookiesUtils'); - -describe('testing cookiesUtils', () => { - beforeEach(() => { - cookie.parse.mockImplementation(() => ({ - KEYCLOAK_AWS_undefined: 'testSession', - KEYCLOAK_AWS_SESSION: 'sessionId', - })); - }); - - afterEach(() => { - }); - - test('test clearCookies', async () => { - const newResponseHeaders = cookiesUtils.clearCookies({ - headers: { - cookie: [{ - value: 'testCookie', - }], - }, - }, { keycloakJson: () => {} }, {}); - expect(newResponseHeaders).toEqual({ - 'set-cookie': [ - { - key: 'Set-Cookie', - }, - ], - }); - }); - - test('test getCookies', async () => { - const newResponseHeaders = cookiesUtils.getCookies({ - headers: { - cookie: [{ - value: 'testCookie', - }], - }, - }, {}, {}); - expect(newResponseHeaders).toEqual({ - 'set-cookie': [ - { - key: 'Set-Cookie', - }, - { - key: 'Set-Cookie', - }, - ], - }); - }); - - test('test getCookie', async () => { - const cs = cookiesUtils.getCookie({ - headers: { - cookie: [{ - value: 'testCookie', - }], - }, - }); - expect(cs).toEqual({ - session: 'sessionId', - sessionToken: 'sessionId', - }); - }); - - test('test getCookie null', async () => { - const cs = cookiesUtils.getCookie({ - headers: { - }, - }); - expect(cs).toEqual(null); - }); - - test('test getCookie null 2', async () => { - cookie.parse.mockImplementation(() => ({ - })); - const cs = cookiesUtils.getCookie({ - headers: { - cookie: [{ - value: 'testCookie', - }], - }, - }); - expect(cs).toEqual(null); - }); -}); diff --git a/example/keycloak-cloudfront-portal/README.md b/example/keycloak-cloudfront-portal/README.md deleted file mode 100644 index c31b4d8..0000000 --- a/example/keycloak-cloudfront-portal/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# Cloudfront(Lambda:edge) with portal authorization (Cross-realm authentication) - -Solution how to logged in to one realm and then switching to another realms without asking the password. - -## 1. Start Keycloak - -### Docker -1. Using the image from https://hub.docker.com/r/jboss/keycloak/ -``` -docker run -p 8080:8080 -e JAVA_OPTS="-Dkeycloak.profile.feature.scripts=enabled -Dkeycloak.profile.feature.upload_scripts=enabled -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true" -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin jboss/keycloak -``` -2. **Open the Keycloak admin console, click on Add Realm, click on import 'Select file', select [portal-realm.json](portal-realm.json) and click Create.** -3. **Open the Keycloak admin console, click on Add Realm, click on import 'Select file', select [securityRealm1.json](securityRealm1.json) and click Create.** -4. **Open the Keycloak admin console, click on Add Realm, click on import 'Select file', select [securityRealm2.json](securityRealm2.json) and click Create.**] -5. change JWKS URL for SecurityRealm1: -replace with http://:8080/cert instead of http://localhost:8080/cert ![securityRealm1](../../docs/securityRealm1.png) -6. change JWKS URL for SecurityRealm2: -replace with http://:8080/cert instead of http://localhost:8080/cert -### Standard -1. Download Keycloak from https://www.keycloak.org/downloads -``` -sh bin/standalone.sh -c standalone.xml -b 0.0.0.0 -Djboss.bind.address.management=0.0.0.0 --debug 8190 -Djboss.http.port=8090 -``` -``` -2. **Open the Keycloak admin console, click on Add Realm, click on import 'Select file', select [portal-realm.json](portal-realm.json) and click Create.** -3. **Open the Keycloak admin console, click on Add Realm, click on import 'Select file', select [securityRealm1.json](securityRealm1.json) and click Create.** -4. **Open the Keycloak admin console, click on Add Realm, click on import 'Select file', select [securityRealm2.json](securityRealm2.json) and click Create.**] - - -### Run emulation cloudfront and lambda:edge locally - -```bash -cd lambda-edge-example -npm i -cd .. -npm i -npm run start -``` - -### Deploy to cloud using aws CDK -```bash -cd keycloak-cloudfront-cdk -./deploy.sh -n "" -r "arn:aws:iam:::role/" -``` - -### Portal Users: - -| Portal User | Portal password | Security Realm 1 | Security Realm 1 | -|:------------|:----------------|:-----------------|:-----------------| -| user | user | X | X | -| user1 | user1 | X | - | -| user2 | user2 | - | X | - -### Switch Tenant: - -Tenant Selector : ![tenantSelector](../../docs/tenantSelector.png) -Select to Security Tenant 1: ![SelectTenant1](../../docs/SelectTenant1.png) -Select to Security Tenant 2: ![SelectTenant2](../../docs/SelectTenant2.png) \ No newline at end of file diff --git a/example/keycloak-cloudfront-portal/babel.config.js b/example/keycloak-cloudfront-portal/babel.config.js deleted file mode 100644 index 007836c..0000000 --- a/example/keycloak-cloudfront-portal/babel.config.js +++ /dev/null @@ -1,43 +0,0 @@ -module.exports = function (api) { - api.cache(true); - - const presets = [ - [ - '@babel/preset-env', - { - targets: { - esmodules: true, - }, - }, - ], - ['@babel/preset-react'], - ['@babel/preset-flow'] - ]; - - const plugins = [ - ['@babel/transform-runtime', { - helpers: false, - regenerator: true, - }], - ['@babel/plugin-proposal-decorators', { legacy: true }], - ['@babel/plugin-proposal-class-properties', { loose: true }], - '@babel/plugin-transform-object-assign', - '@babel/plugin-proposal-do-expressions', - '@babel/plugin-proposal-export-default-from', - '@babel/plugin-proposal-object-rest-spread', - '@babel/plugin-proposal-function-sent', - '@babel/plugin-proposal-optional-chaining', - '@babel/plugin-proposal-partial-application', - ]; - - if (process.env.NODE_ENV === 'test') { - plugins.push('babel-plugin-dynamic-import-node'); - } else { - plugins.push('@babel/plugin-syntax-dynamic-import'); - } - - return { - presets, - plugins, - }; -}; diff --git a/example/keycloak-cloudfront-portal/index.html b/example/keycloak-cloudfront-portal/index.html deleted file mode 100644 index a63f074..0000000 --- a/example/keycloak-cloudfront-portal/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - CloudFront/Lambda:edge example - - -
- - diff --git a/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/cdk.json b/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/cdk.json deleted file mode 100644 index 8ff3dbf..0000000 --- a/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/cdk.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "app": "node index.js" -} \ No newline at end of file diff --git a/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/deploy.sh b/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/deploy.sh deleted file mode 100755 index 57cb270..0000000 --- a/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/deploy.sh +++ /dev/null @@ -1,79 +0,0 @@ -set -e - -function help -{ -echo ' -Usage deploy.sh OPTIONS - -deploy keycloak-cloudfront infrastructure - -Options: - -n, --name REQUIRED uniq id - -r, --role REQUIRED arnRole - --profile aws profile - --help Help screen -' -} - -POSITIONAL=() -while [[ $# -gt 0 ]] -do -key="$1" - -case $key in - -n|--name) - BUCKET_NAME="$2" - shift - shift - ;; - -r|--role) - ROLE="$2" - shift - shift - ;; - -profile) - PROFILE="$2" - shift - shift - ;; - --help) - help - exit - ;; - *) # unknown option - POSITIONAL+=("$1") # save it in an array for later - shift # past argument - ;; -esac -done - -set -- "${POSITIONAL[@]}" # restore positional parameters - -if [[ "x${BUCKET_NAME}" = "x" ]]; then - echo "Error: bucket name is required" - help - exit 1; -fi - -if [[ "x${ROLE}" = "x" ]]; then - echo "Error: Arn Role is required" - help - exit 1; -fi -#npm i aws-cdk -g -#npm i -#npm run build -export AWS_DEFAULT_REGION=us-east-1 -#export stackName="example-${BUCKET_NAME}" -export bucketName="${BUCKET_NAME}" -export arnRole="${ROLE}" - -if [[ "x${PROFILE}" = "x" ]]; then - cdk -v bootstrap - cdk -v deploy - exit 0; -fi - -cdk -v bootstrap --profile="${PROFILE}" -cdk -v deploy --profile="${PROFILE}" - diff --git a/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/index.js b/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/index.js deleted file mode 100644 index e2387ff..0000000 --- a/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/index.js +++ /dev/null @@ -1,103 +0,0 @@ -const cdk = require('@aws-cdk/core'); -const iam = require('@aws-cdk/aws-iam'); -const dynamodb = require('@aws-cdk/aws-dynamodb'); -const s3 = require('@aws-cdk/aws-s3'); -const s3Deployment = require('@aws-cdk/aws-s3-deployment'); -const lambda = require('@aws-cdk/aws-lambda'); -const cloudfront = require('@aws-cdk/aws-cloudfront'); - -const { bucketName } = process.env; -const tableName = 'exampleSessionTable'; -const roleArn = process.env.arnRole; - -class KeycloakCloudFrontExampleStack extends cdk.Stack { - constructor(parent, id, props) { - super(parent, id, props); - - const role = iam.Role.fromRoleArn(this, `Role ${bucketName}`, roleArn, { mutable: false }); - const bucket = new s3.Bucket(this, 'lambda-edge-bucket', { - accessControl: s3.BucketAccessControl.AUTHENTICATED_READ, - removalPolicy: cdk.RemovalPolicy.DESTROY, - publicReadAccess: false, - blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, - bucketName, - }); - - const lambdaEdge = new lambda.Function(this, 'lambda-edge-example', { - runtime: lambda.Runtime.NODEJS_12_X, - handler: 'index.lambda', - code: lambda.Code.fromAsset('../lambda-edge-example/dist'), - functionName: `function_${bucketName}`, - role, - memorySize: 128, - timeout: cdk.Duration.seconds(5), - }); - const VersionLambdaEdge = new lambda.Version(this, 'lambda-edge-example Version', { - lambda: lambdaEdge, - description: `lambda-edge-example Version ${Math.random() * (99999 - 1) + 1}`, - }); - - const accessIdentityId = `access-identity-${bucketName}`; - - const comment = `OriginAccessIdentity-${bucketName}`; - const oai = new cloudfront.OriginAccessIdentity(this, accessIdentityId, { - comment, - }); - - bucket.addToResourcePolicy(new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - principals: [oai.grantPrincipal], - actions: ['s3:GetObject'], - resources: [`arn:aws:s3:::${bucketName}/*`], - })); - const sessionTable = new dynamodb.Table(this, `Session ${bucketName}`, { - tableName, - partitionKey: { name: 'session', type: dynamodb.AttributeType.STRING }, - removalPolicy: cdk.RemovalPolicy.DESTROY, - timeToLiveAttribute: 'exp', - }); - sessionTable.grantFullAccess(role); - const frontWebDistribution = new cloudfront.CloudFrontWebDistribution(this, `cloudfront-${bucketName}`, { - originConfigs: [{ - s3OriginSource: { - s3BucketSource: bucket, - originAccessIdentity: oai, - }, - behaviors: [ - { - isDefaultBehavior: true, - allowedMethods: cloudfront.CloudFrontAllowedMethods.ALL, - forwardedValues: { - cookies: { forward: 'all' }, - headers: [ - 'Authorization', - 'Referer', - 'Origin', - ], - queryString: true, - }, - lambdaFunctionAssociations: [{ - lambdaFunction: VersionLambdaEdge, - eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST, - }], - }, - ], - }], - viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, - defaultRootObject: 'index.html', - }); - // eslint-disable-next-line no-new - new s3Deployment.BucketDeployment(this, `BucketDeployment ${bucket}`, { - destinationBucket: bucket, - role, - distribution: frontWebDistribution, - sources: [ - s3Deployment.Source.asset('../public'), - ], - }); - } -} -const app = new cdk.App(); -// eslint-disable-next-line no-new -new KeycloakCloudFrontExampleStack(app, `example-${bucketName}`); -app.synth(); diff --git a/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/package.json b/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/package.json deleted file mode 100644 index b294be5..0000000 --- a/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "keycloak-cloudfront-cdk", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "build": "cd ../lambda-edge-example && npm i && npm run link:dep && npm run build && cd .. && npm i && npm run build", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "vzakharchenko", - "license": "Apache-2.0", - "dependencies": { - "@aws-cdk/aws-cloudfront": "^1.100.0", - "@aws-cdk/aws-dynamodb": "^1.100.0", - "@aws-cdk/aws-lambda": "^1.100.0", - "@aws-cdk/aws-s3": "^1.100.0", - "@aws-cdk/aws-s3-deployment": "^1.100.0", - "@aws-cdk/core": "^1.100.0" - } -} diff --git a/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/yarn.lock b/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/yarn.lock deleted file mode 100644 index 918a729..0000000 --- a/example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk/yarn.lock +++ /dev/null @@ -1,336 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@aws-cdk/assets@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/assets/-/assets-1.41.0.tgz#ac48e4a17603fd1b43f8f07cc308c75a70cb34e6" - integrity sha512-2Nz7MzO0k/HJwmeLCNMqs1feIFVCiII0AbXTgfTuHZ/IO2fZ0hRrYPr5lr/SCBLjPj6U5OtwMmKo4xt2U5qY0Q== - dependencies: - "@aws-cdk/core" "1.41.0" - "@aws-cdk/cx-api" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-applicationautoscaling@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-applicationautoscaling/-/aws-applicationautoscaling-1.41.0.tgz#be65759b39c88eea4bfb3e2874e14e9efcf922b8" - integrity sha512-K0nmvEVlCLSO0K/8Np0Do8biMpetpBxbQqS6i9I6B4U/r8m5QAgU8UhEo0zYygDbiyWsTEne7zPI679hvQhxhQ== - dependencies: - "@aws-cdk/aws-autoscaling-common" "1.41.0" - "@aws-cdk/aws-cloudwatch" "1.41.0" - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-autoscaling-common@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-autoscaling-common/-/aws-autoscaling-common-1.41.0.tgz#e9f07efb8bb498e0076c620e712630191f33b0d9" - integrity sha512-fMlAz7cJUv+thVnUssG+/zL8th/vJob0NlkY/E4dXn9i9OkYtvF7SN5ek2Eki/t/iSfemYEKqX/LWWolfUfozw== - dependencies: - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-certificatemanager@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-certificatemanager/-/aws-certificatemanager-1.41.0.tgz#0a90f3a5d30bec324e2cd9d29594113a0e8cd723" - integrity sha512-h2RnymJugNHkc3NAjARrUoR4AKMxqa+zVNbWX47vqoTCTGdlwScQu21h5+O0apFUU1hbtHlcDq7GAkaGLN6yGw== - dependencies: - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/aws-lambda" "1.41.0" - "@aws-cdk/aws-route53" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-cloudformation@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-cloudformation/-/aws-cloudformation-1.41.0.tgz#d5e94eceb0a47192f94db4f3fbde9e9a9a3f63a2" - integrity sha512-kg2bXC3MPdM46NgaVYZLsvTRg7dZ4ZoDR//vMXQUrCzncM3cCJUayWc4VkmqIfV8x6L3n1nzokmNX+i8FA3WKw== - dependencies: - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/aws-lambda" "1.41.0" - "@aws-cdk/aws-s3" "1.41.0" - "@aws-cdk/aws-sns" "1.41.0" - "@aws-cdk/core" "1.41.0" - "@aws-cdk/cx-api" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-cloudfront@1.41.0", "@aws-cdk/aws-cloudfront@^1.32.2": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-cloudfront/-/aws-cloudfront-1.41.0.tgz#171262f992fbb91e04566122452030b67add22c1" - integrity sha512-T+26stl2M4EjDyE6AqqjdM+0FWrofZlhklgYOjt+TOEgFDAE/OYbCJAR+MFZaC2OFEikq28MW4Qma+JpKelKsw== - dependencies: - "@aws-cdk/aws-certificatemanager" "1.41.0" - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/aws-kms" "1.41.0" - "@aws-cdk/aws-lambda" "1.41.0" - "@aws-cdk/aws-s3" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-cloudwatch@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-cloudwatch/-/aws-cloudwatch-1.41.0.tgz#a8068bfd80bc0bed19d52314c1c2cc2fdb2b0cb8" - integrity sha512-fIEzfzkCDZRHH63pMKuc5+CaAKS2pskscLIETEGz1OOCjAS6Wfy955n6UFtbQa+vpr0koGPTx6AmVn5n28N7Uw== - dependencies: - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-dynamodb@^1.32.2": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-dynamodb/-/aws-dynamodb-1.41.0.tgz#53855dce746f415cd8567b40d7be0c765d83e11a" - integrity sha512-40DfoXn2MjUvib0le3E6k2YX6+JsGPGR6CFPIl/p95F4E/0uPHOmDDBAeYf/Y0W1SkWAkrTFBbRq2FBzFCrRLQ== - dependencies: - "@aws-cdk/aws-applicationautoscaling" "1.41.0" - "@aws-cdk/aws-cloudwatch" "1.41.0" - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/aws-kms" "1.41.0" - "@aws-cdk/aws-lambda" "1.41.0" - "@aws-cdk/core" "1.41.0" - "@aws-cdk/custom-resources" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-ec2@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-ec2/-/aws-ec2-1.41.0.tgz#e41c09ae5302c20269c622ee5752fa74ae23e5cf" - integrity sha512-DWxmAlSDjZngYn4XENicvOv24wRBEfCVOwQLeo9gVkhj7r8KhdMB2CNSRN+kAzYVZYpBFcDRE52gsd0CMRy/1g== - dependencies: - "@aws-cdk/aws-cloudwatch" "1.41.0" - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/aws-logs" "1.41.0" - "@aws-cdk/aws-s3" "1.41.0" - "@aws-cdk/aws-ssm" "1.41.0" - "@aws-cdk/cloud-assembly-schema" "1.41.0" - "@aws-cdk/core" "1.41.0" - "@aws-cdk/cx-api" "1.41.0" - "@aws-cdk/region-info" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-events@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-events/-/aws-events-1.41.0.tgz#01138ac1da6d27d4181575db4c97f88398487a9f" - integrity sha512-1D4ATsE3rnUATlv2VdJod9bXmNxl7x+YJgcWPd2KLU7gXPxyAb7zCG0QeUDcBagKLD2OHjpeXNo/3tpH7ZbEtA== - dependencies: - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-iam@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-iam/-/aws-iam-1.41.0.tgz#b9f8fd0e0791b76a849367045a79974cda1fef2b" - integrity sha512-1pblFd9JPOqChNyMMlTFf5VdYfXeysuokJhDJE+udZGlxgb8yqQiAmukuB0BdueJsaHVQdyQOz5QenPN5bUvUw== - dependencies: - "@aws-cdk/core" "1.41.0" - "@aws-cdk/region-info" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-kms@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-kms/-/aws-kms-1.41.0.tgz#5cb286813e502cd9eb17e570be7b6b4368acaddd" - integrity sha512-YZZ7ACKMTeCd7NLLPmaZ8eMba4La9HvShQbSvqzU9fixVh5DfLFFGyj/BhWZ1Mx7lLFWG4PCJHMyR8TFELcU5w== - dependencies: - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-lambda@1.41.0", "@aws-cdk/aws-lambda@^1.32.2": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-lambda/-/aws-lambda-1.41.0.tgz#be31c46a48906951252e8892966b2f0ebdb94d47" - integrity sha512-uQyaWcyjTvnnjBeJ0qzc8qRujYt68kv3TVtOKqlRbrIA97wy6pt4QhKinHuF8me96OfsdkIxNyfelr0QN0tHTg== - dependencies: - "@aws-cdk/aws-cloudwatch" "1.41.0" - "@aws-cdk/aws-ec2" "1.41.0" - "@aws-cdk/aws-events" "1.41.0" - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/aws-logs" "1.41.0" - "@aws-cdk/aws-s3" "1.41.0" - "@aws-cdk/aws-s3-assets" "1.41.0" - "@aws-cdk/aws-sqs" "1.41.0" - "@aws-cdk/core" "1.41.0" - "@aws-cdk/cx-api" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-logs@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-logs/-/aws-logs-1.41.0.tgz#a730e4ae8f3f11a4640909b2d44e9815dbe7de82" - integrity sha512-P8eSzGiXOEMMoc0DGP1bK1t+3F1k2LmqKh0AFPJTvo/ZXUBFvEnY+gWcLs83bx4u3mEjlqXi/o5BRa7EJkkHow== - dependencies: - "@aws-cdk/aws-cloudwatch" "1.41.0" - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-route53@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-route53/-/aws-route53-1.41.0.tgz#e25cbc61368f39da450b81b8cbb5186fff9b7345" - integrity sha512-llp53PbiqJXNsd1W4xJgWndY122AkqSQWdUhV07KpJEVmRwo6yzvbHcM2/m5kSWqwNtZQZOsNx7t57gRVsjffQ== - dependencies: - "@aws-cdk/aws-ec2" "1.41.0" - "@aws-cdk/aws-logs" "1.41.0" - "@aws-cdk/cloud-assembly-schema" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-s3-assets@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-s3-assets/-/aws-s3-assets-1.41.0.tgz#40d27cae6a3facb0d2d0bf1da8e0ddb302e09960" - integrity sha512-hGt+7qEkGz6CMLi47ZSzonKcRThLC2ma/DMrQbbF0ikeupPLK2SsRQ4EIadH69zGr6fz8u0wbWPfMaJGgESolQ== - dependencies: - "@aws-cdk/assets" "1.41.0" - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/aws-s3" "1.41.0" - "@aws-cdk/core" "1.41.0" - "@aws-cdk/cx-api" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-s3-deployment@^1.32.2": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-s3-deployment/-/aws-s3-deployment-1.41.0.tgz#f739b48be5277f2ec0bb8d087f10a393136be7a1" - integrity sha512-YcurMrLMqhwf/fPeyAwCO/kCbetpriN+ny9QvSIEWrzdPVc+eN1q7I7Jf67fVjIy2Calv7eRhsAAAe4s8OYHrw== - dependencies: - "@aws-cdk/aws-cloudfront" "1.41.0" - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/aws-lambda" "1.41.0" - "@aws-cdk/aws-s3" "1.41.0" - "@aws-cdk/aws-s3-assets" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-s3@1.41.0", "@aws-cdk/aws-s3@^1.32.2": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-s3/-/aws-s3-1.41.0.tgz#27da9f94632a880f380a20647810c23ab291b395" - integrity sha512-B7uhPOLqUx5xkpF7YX0E5mwjYM0wZQLkT5Jh/cGohPKwfMlGELjmNjeudC5naImTqL0a6VflXza7+d+4lVLdFw== - dependencies: - "@aws-cdk/aws-events" "1.41.0" - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/aws-kms" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-sns@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-sns/-/aws-sns-1.41.0.tgz#428c312f4632f7c9a393e11f4eae44c49dbea87d" - integrity sha512-+tvtIuYah8tVsEOJ8+8+UqEils/H7VEBqV0FBO5K0yjKO6b4QLiRFB+GviZA6kJ0p8uUBzZl7RYkjMyS2cYN7w== - dependencies: - "@aws-cdk/aws-cloudwatch" "1.41.0" - "@aws-cdk/aws-events" "1.41.0" - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/aws-kms" "1.41.0" - "@aws-cdk/aws-sqs" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-sqs@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-sqs/-/aws-sqs-1.41.0.tgz#6a99cb78a34b4a8b3223f2d6e53fc617e36ca125" - integrity sha512-03wf4Rort6jlmx/xrNUN2ld/5KmuyEw28jyL7dDFVsfGglXw69bPjuRMtTWkSfbYWPbFlGbKR16IiyKzRFF4oA== - dependencies: - "@aws-cdk/aws-cloudwatch" "1.41.0" - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/aws-kms" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/aws-ssm@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/aws-ssm/-/aws-ssm-1.41.0.tgz#27a4e3d446d245fe1e1d348cc53bdc8e511b2166" - integrity sha512-w43rka1ltQp2myR3u5mM/E7uNwmf7k5tvSgLoHQcU/p5iIPCL+R5ZvrJlOTaGRjRZlzq+CGt4+QKOSZveUtG9A== - dependencies: - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/aws-kms" "1.41.0" - "@aws-cdk/cloud-assembly-schema" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/cdk-assets-schema@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/cdk-assets-schema/-/cdk-assets-schema-1.41.0.tgz#0c42e188149a0ab25eea495098f2adafb6413c4d" - integrity sha512-lB/YAnoYoTq09Z5DAzg3eLJQZwkyFIopYg2a5Y1GlpDfgRoNAxb0rjgDfp68dVeBbisID2AfczdVv6Mhq/xzFQ== - dependencies: - semver "^7.2.2" - -"@aws-cdk/cloud-assembly-schema@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-1.41.0.tgz#7e5f96069881ef9aa24efaef79a3101850d79e78" - integrity sha512-13uULbrkiO07KEhn2E77QgfFjq2qrrR4sevi85hVgwCo0QN5ZWyYJzyWpVphaXRcY2vTHUI+/KgFtgwDMdplqQ== - dependencies: - jsonschema "^1.2.5" - semver "^7.2.2" - -"@aws-cdk/core@1.41.0", "@aws-cdk/core@^1.32.2": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/core/-/core-1.41.0.tgz#bda0f07ea38687f699c62e02f6cb08edcfd75d23" - integrity sha512-6hHNpXA7tbceOKxIeVnRCKVKZe7Bf/bZ/UgqB7/XcdAxdn8HIvo/lY3cb64zqRL3b04pjsvgoF/8wU92edj/uA== - dependencies: - "@aws-cdk/cdk-assets-schema" "1.41.0" - "@aws-cdk/cloud-assembly-schema" "1.41.0" - "@aws-cdk/cx-api" "1.41.0" - constructs "^3.0.2" - minimatch "^3.0.4" - -"@aws-cdk/custom-resources@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/custom-resources/-/custom-resources-1.41.0.tgz#ab0b48d02ef2b8dc77c0e4479285287dd3088d8b" - integrity sha512-hXdsyoGR4SnQfHi3S7HMH4qToOYVCB7ofv18CFvsUHxxdq42gUeoXboWUdPCFDi/gEHhoShEeccVeakQrOAaMA== - dependencies: - "@aws-cdk/aws-cloudformation" "1.41.0" - "@aws-cdk/aws-iam" "1.41.0" - "@aws-cdk/aws-lambda" "1.41.0" - "@aws-cdk/aws-logs" "1.41.0" - "@aws-cdk/aws-sns" "1.41.0" - "@aws-cdk/core" "1.41.0" - constructs "^3.0.2" - -"@aws-cdk/cx-api@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/cx-api/-/cx-api-1.41.0.tgz#0891c7e8e9d7144f2d31fa0ac701b0db80873784" - integrity sha512-rX0EVVkCAeDvmJMMolRLeHCOufKEMuBvIkc8E7PV9zgQCqKuV5MV7sZ5cXWDiE8kbPGQx8B6ipsDvRwi5Z7//Q== - dependencies: - "@aws-cdk/cloud-assembly-schema" "1.41.0" - semver "^7.2.2" - -"@aws-cdk/region-info@1.41.0": - version "1.41.0" - resolved "https://registry.yarnpkg.com/@aws-cdk/region-info/-/region-info-1.41.0.tgz#02800320b5ac9e17a0a1f2b067580cabf3b114b6" - integrity sha512-NjeVkpK/dnhK+JPDzkrTCtA5GANs28DtitvlVVDbO8JKYGMTZbjqznS2LyuMP3Idx82lCJ8eL6zstMiQaTmBaw== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -constructs@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/constructs/-/constructs-3.0.3.tgz#76687d6e3783b0b6864d72aaae5b0bacd824d52e" - integrity sha512-JrYLpTlz92Un1jxkwoGiOiGoDjzIWtxo64sLC5FD4mQN1H9mAqZNvgxWYWaJIiWUXNkl5L5sO3GFf6peTj7UMQ== - -jsonschema@^1.2.5: - version "1.2.6" - resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.6.tgz#52b0a8e9dc06bbae7295249d03e4b9faee8a0c0b" - integrity sha512-SqhURKZG07JyKKeo/ir24QnS4/BV7a6gQy93bUSe4lUdNp0QNpIz2c9elWJQ9dpc5cQYY6cvCzgRwy0MQCLyqA== - -minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -semver@^7.2.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== diff --git a/example/keycloak-cloudfront-portal/lambda-edge-example/babel.config.js b/example/keycloak-cloudfront-portal/lambda-edge-example/babel.config.js deleted file mode 100644 index 5b67f34..0000000 --- a/example/keycloak-cloudfront-portal/lambda-edge-example/babel.config.js +++ /dev/null @@ -1,33 +0,0 @@ -module.exports = function (api) { - api.cache(true); - - const presets = [ - [ - '@babel/preset-env', - { - targets: { - esmodules: true, - }, - }, - ], - ]; - const plugins = [ - ['@babel/transform-runtime', { - helpers: false, - regenerator: true, - }], - ['@babel/plugin-proposal-decorators', { decoratorsBeforeExport: true }], - ['@babel/plugin-proposal-object-rest-spread'], - ]; - - if (process.env.NODE_ENV === 'test') { - plugins.push('babel-plugin-dynamic-import-node'); - } else { - plugins.push('@babel/plugin-syntax-dynamic-import'); - } - - return { - presets, - plugins, - }; -}; diff --git a/example/keycloak-cloudfront-portal/lambda-edge-example/index.js b/example/keycloak-cloudfront-portal/lambda-edge-example/index.js deleted file mode 100644 index 831d2f4..0000000 --- a/example/keycloak-cloudfront-portal/lambda-edge-example/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import { authorization } from './src/index'; - -// eslint-disable-next-line import/prefer-default-export -export const lambda = authorization; diff --git a/example/keycloak-cloudfront-portal/lambda-edge-example/jest.config.js b/example/keycloak-cloudfront-portal/lambda-edge-example/jest.config.js deleted file mode 100644 index 2350bb8..0000000 --- a/example/keycloak-cloudfront-portal/lambda-edge-example/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - setupFiles: ['./unitTestConfig/jestSetup.js'], - transform: { - '^.+\\.js$': 'babel-jest', - }, - transformIgnorePatterns: ['/node_modules/'], -}; diff --git a/example/keycloak-cloudfront-portal/lambda-edge-example/package.json b/example/keycloak-cloudfront-portal/lambda-edge-example/package.json deleted file mode 100644 index b7fe441..0000000 --- a/example/keycloak-cloudfront-portal/lambda-edge-example/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "lambda-edge-example", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "build": "NODE_ENV=production webpack --config webpack.config.babel.js", - "link:dep": "cd ../../.. && npm link && cd example/keycloak-cloudfront/lambda-edge-example && npm link keycloak-lambda-authorizer", - "test": "jest --maxWorkers=2" - }, - "author": "vzakharchenko", - "license": "Apache-2.0", - "devDependencies": { - "@babel/core": "^7.13.16", - "@babel/plugin-proposal-decorators": "^7.13.15", - "@babel/plugin-proposal-object-rest-spread": "^7.13.8", - "@babel/plugin-transform-runtime": "^7.13.15", - "@babel/preset-env": "^7.13.15", - "@babel/register": "^7.13.16", - "babel-jest": "^26.6.3", - "babel-loader": "^8.2.2", - "enzyme": "^3.11.0", - "jest": "^26.6.3", - "jest-date-mock": "^1.0.8", - "progress-bar-webpack-plugin": "^2.1.0", - "webpack": "^5.35.0", - "webpack-cli": "^4.6.0" - }, - "dependencies": { - "@babel/runtime": "^7.13.17", - "axios": "^0.21.1", - "cookie": "^0.4.1", - "crypto-js": "^4.0.0", - "jsonwebtoken": "^8.5.1", - "jws": "^4.0.0", - "keycloak-lambda-authorizer": "../../../", - "node-cache": "^5.1.2", - "node-forge": "^0.10.0", - "querystring": "^0.2.1", - "rsa-pem-to-jwk": "^1.1.3", - "keycloak-cloudfront-dynamodb": "^0.1.4", - "uuid": "^8.3.2" - } -} diff --git a/example/keycloak-cloudfront-portal/lambda-edge-example/src/Tentants.js b/example/keycloak-cloudfront-portal/lambda-edge-example/src/Tentants.js deleted file mode 100644 index 2e9a8db..0000000 --- a/example/keycloak-cloudfront-portal/lambda-edge-example/src/Tentants.js +++ /dev/null @@ -1,58 +0,0 @@ -import { privateKey, publicKey } from './sessionKeys'; - -export const portalKeycloakJSON = { - realm: 'portal', - 'auth-server-url': 'http://127.0.0.1:8080/auth/', - 'ssl-required': 'external', - resource: 'portal-ui', - credentials: { - secret: 'ece2012c-fc01-4dca-b50b-f898c9c6c811', - }, - 'confidential-port': 0, -}; - -function getRealmCallback(uri) { - return uri && uri.includes('/securityRealmClient') ? uri.split('/')[uri.split('/').length - 3] : null; -} - -function getRealm(options) { - const { uri } = options.request; - return uri && uri.startsWith('/tenants') ? uri.split('/')[2] : getRealmCallback(uri); -} - -export function tenantKeycloakJson(options) { - return { - realm: getRealm(options), - 'auth-server-url': 'http://localhost:8080/auth', - 'ssl-required': 'external', - resource: 'securityRealmClient', - credentials: { - jwt: { - }, - }, - 'confidential-port': 0, - }; -} - -export const tenantOptions = { - keys: { - privateKey, - publicKey, - }, - sessionModify: (sessionToken, token, options) => { - const keycloakJson = options.keycloakJson(options); - const newSessionToken = { ...sessionToken }; - Object.keys(newSessionToken.tenants).forEach((realm) => { - Object.keys(newSessionToken.tenants[realm]).forEach((clientId) => { - newSessionToken.tenants[realm][clientId].status = realm === keycloakJson.realm && clientId === keycloakJson.resource ? 'Active' : 'InActive'; - }); - }); - return newSessionToken; - }, - enforce: { - enabled: true, - resource: { - name: 'securityRealmResource', - }, - }, -}; diff --git a/example/keycloak-cloudfront-portal/lambda-edge-example/src/index.js b/example/keycloak-cloudfront-portal/lambda-edge-example/src/index.js deleted file mode 100644 index 80f6f3b..0000000 --- a/example/keycloak-cloudfront-portal/lambda-edge-example/src/index.js +++ /dev/null @@ -1,49 +0,0 @@ -import { lamdaEdge } from 'keycloak-lambda-authorizer'; -import { SessionManager } from 'keycloak-lambda-authorizer/src/edge/storage/SessionManager'; -import { LocalSessionStorage } from 'keycloak-lambda-authorizer/src/edge/storage/localSessionStorage'; -import { DynamoDbSessionStorage } from 'keycloak-cloudfront-dynamodb/DynamoDbSessionStorage'; -import { privateKey, publicKey } from './sessionKeys'; -import { - portalKeycloakJSON, - tenantKeycloakJson, - tenantOptions, -} from './Tentants'; - -lamdaEdge.routes.addJwksEndpoint('/cert', publicKey.key); - -function tenantResponseHandler(request, options) { - const { uri } = request; - const keycloakJson = options.keycloakJson(options); - if (uri.startsWith(`/tenants/${keycloakJson.realm}/api`)) { - return { - status: '200', - statusDescription: 'OK', - body: JSON.stringify({ tenant: keycloakJson.realm, status: 'success' }), - }; - } - return request; -} - -lamdaEdge.routes.addProtected([new RegExp('(^)(\\/|)(/tenants/(.*))(/$|(\\?|$))', 'g')], - tenantKeycloakJson, - { - ...tenantOptions, - ...{ responseHandler: tenantResponseHandler }, - }); -lamdaEdge.routes.addProtected( - ['/'], - portalKeycloakJSON, -); -// eslint-disable-next-line import/prefer-default-export -export async function authorization(event, context, callback) { - await lamdaEdge.lambdaEdgeRouter(event, context, new SessionManager( - event.localhost ? new LocalSessionStorage() - : new DynamoDbSessionStorage({ region: 'us-east-1' }, 'exampleSessionTable'), - { - keys: { - privateKey, - publicKey, - }, - }, - ), callback); -} diff --git a/example/keycloak-cloudfront-portal/lambda-edge-example/src/sessionKeys.js b/example/keycloak-cloudfront-portal/lambda-edge-example/src/sessionKeys.js deleted file mode 100644 index 5a68e3a..0000000 --- a/example/keycloak-cloudfront-portal/lambda-edge-example/src/sessionKeys.js +++ /dev/null @@ -1,59 +0,0 @@ -const publicKey = '-----BEGIN CERTIFICATE-----\n' - + 'MIIDgzCCAmugAwIBAgIJAJTi4Mu+7fIMMA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV\n' - + 'BAYTAlVTMQ8wDQYDVQQIDAZEZW5pYWwxFDASBgNVBAcMC1NwcmluZ2ZpZWxkMQww\n' - + 'CgYDVQQKDANEaXMxFDASBgNVBAMMC2xhbWJkYS1qd2tzMB4XDTIwMDQxMjA3NDUy\n' - + 'MFoXDTIxMDQxMjA3NDUyMFowWDELMAkGA1UEBhMCVVMxDzANBgNVBAgMBkRlbmlh\n' - + 'bDEUMBIGA1UEBwwLU3ByaW5nZmllbGQxDDAKBgNVBAoMA0RpczEUMBIGA1UEAwwL\n' - + 'bGFtYmRhLWp3a3MwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqtsnm\n' - + 'VbhKd9X1rkNalJO27OmMgF9jT8olOHuyqft1xKak9B04huWWGbCj6Q03Ugp3z9ZP\n' - + 'vcowITEuaQPCRrkLCndTO8K6wSOJ1ygW8tWPkkN0okyiMVb35+0mdqHV/f1F+9PB\n' - + 'IUgFh5F9L3HXtP42pk3NbNfP//o7BAjyN2NBiN+scz2dE/wORJE1sgLi3ICXTp6K\n' - + 'XvzNlXwpWfGv4bRuTxJZ8XAjJfElihtQ6pUKDjRyYMFnx2OltFjSfTl5BiA02slF\n' - + 'TDrf7UjGc3srihCnwCl377MqhCTYK9/NZEkBkAH1yasoWjv1NSXDNAyLGLjlE1w2\n' - + 'SHQ/MwFDAZkig25HAgMBAAGjUDBOMB0GA1UdDgQWBBRD0CkykEVkbA74qJghVg9F\n' - + 'DflQgzAfBgNVHSMEGDAWgBRD0CkykEVkbA74qJghVg9FDflQgzAMBgNVHRMEBTAD\n' - + 'AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAm69bZRa104V7ftm5Sl4BYhH5BGYq+QJG2\n' - + '+vS8S56GO07ExrD+pEPW0LUeFICVf33XFrN3QFGk87MJQVDac7GxV43JB4qsOCj0\n' - + 'Sbe0Vyu+oY/wVthtdv3Z7GuwLS/OsIWRKtYxA0IvIDlQyXXmh8E9fL+ZTNKo0iSi\n' - + 'p/H5lWGBSNrMKZNkjPJ59n6EKiNChMrNsz+nk5C8efhEqopToMfJKr1swI0/jP7l\n' - + '9kmEAZePVJamyYJt+hyN89E5wFvEYuzTOXkQpHZB7achhLnepAZTeWD1814WNHaU\n' - + '/qN33+fW7+7N3qHDm1YGWrxUBnFdczEguG6l2MSHTBVMk+/rp60B\n' - + '-----END CERTIFICATE-----\n'; - -const privateKey = '-----BEGIN PRIVATE KEY-----\n' - + 'MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCqtsnmVbhKd9X1\n' - + 'rkNalJO27OmMgF9jT8olOHuyqft1xKak9B04huWWGbCj6Q03Ugp3z9ZPvcowITEu\n' - + 'aQPCRrkLCndTO8K6wSOJ1ygW8tWPkkN0okyiMVb35+0mdqHV/f1F+9PBIUgFh5F9\n' - + 'L3HXtP42pk3NbNfP//o7BAjyN2NBiN+scz2dE/wORJE1sgLi3ICXTp6KXvzNlXwp\n' - + 'WfGv4bRuTxJZ8XAjJfElihtQ6pUKDjRyYMFnx2OltFjSfTl5BiA02slFTDrf7UjG\n' - + 'c3srihCnwCl377MqhCTYK9/NZEkBkAH1yasoWjv1NSXDNAyLGLjlE1w2SHQ/MwFD\n' - + 'AZkig25HAgMBAAECggEAdU/fNrW5SxNGqOnzxw9K4u2zIKYm5qwyEZnbB0/gSXG1\n' - + 'wq0uV2X750YIKNtCBb4PC357m5iklKZ6kZYAy0SmbHvou/3ZN1T6AwMjvYFqWJr+\n' - + 'V+wgFWUqinmKcmAbnl5H6gu/3Hvubj5XMFumM8Fg4FUwKfad54XUgzGmpCyDvMge\n' - + '+jJYTQDmZaDGFKyc+LXeT/W1r53Xzq4IesZsv91CA4P7sxuSH3+2SIIeKTLBhhxd\n' - + 'wzjdZ7jZhOWnxsGcJaQWS0T9mbeRnIPT153bNBYPIaP4p5yPgUdzad/UyGiY6nO1\n' - + 'xJ48Pf6/WspK7t54zRTEJkb9gZvu8w2pMyupAMBW4QKBgQDSMOeKx1cStL9K4APV\n' - + '8j7PH//sbKBQea3pV1aC9EiYhj9kmeaIEGHKZBc6nTaJ8tCvET67jymPqJLBqyPU\n' - + 'ef87YelAgD3XV42vorTHXJX+9DU58YKpblirdjVYpcoPNlke3cRde01NGw5S6JSh\n' - + 'e9nNIjTccVqZTjLNdSrrgmKWuwKBgQDP61xMuaCypuaL/mYoLiZfgpuVjO7nAooy\n' - + 'KMM/Z0D34tfRRWbCLOdchz0iWT+0F7rTzY1uOuW3cYdKdU7IS2aBPO0p6rPgCsOY\n' - + 'WNO36a9zxPEghshm21lDZYl8t4Wp5PjnXdjepequ0KNYrfVj2rar8V83cDOWarAN\n' - + 'PJwyXSi75QKBgGP0uce3cGMG7Ylv6qMNpmzdbNlD9yEOHHRBAnUYMoXGIdN3lLfU\n' - + 'Ao06+Aj5xnvnqvH2I30SYdNdeRz8g/eBZK0arM/trHsBufFyUMIV94bdH4rEnTxx\n' - + 'q10uw8O6Y9LEJ7GUCNPj1Sj72t32mOgKe9Mflz/V8B3DoEkwlQ6WXMgNAoGAGflB\n' - + '94e87nRxGo32PxC81HOhcgZAFfW4Q9nZwkLo186rvUXZN2qaoHF4jqDtl1bbjPgB\n' - + 'sgKDje4Nw5xx8g2RSZXN3s2mGNffZVm7YR89Ps4cfT65LDg8p3G4wi6+8OFcwrJz\n' - + 'lCTP83S24y4gGJBK/6HQjkFjAGhlg9HNhXEj1I0CgYBm2UOnqZ+c6Eg4m0kNlcbW\n' - + 'PLJjiOd1ahc7lSMkep6kXG9MKqiyvfvbbIkRLIxU7s8W+TG0vNJxUrXzWg9FM3Sp\n' - + 'JEr8I4E1mzB26LwvEame9bGtV9rJJEKH1JgcL5L4Yny52vAGUoC8n4bN6vRb51M2\n' - + 'aSV+AcDJyQBwjvRjN8kfdQ==\n' - + '-----END PRIVATE KEY-----\n'; - -module.exports = { - privateKey: { - key: privateKey, - }, - publicKey: { - key: publicKey, - }, -}; diff --git a/example/keycloak-cloudfront-portal/lambda-edge-example/webpack.config.babel.js b/example/keycloak-cloudfront-portal/lambda-edge-example/webpack.config.babel.js deleted file mode 100644 index 70bf632..0000000 --- a/example/keycloak-cloudfront-portal/lambda-edge-example/webpack.config.babel.js +++ /dev/null @@ -1,50 +0,0 @@ -const webpack = require('webpack'); -const ProgressBarPlugin = require('progress-bar-webpack-plugin'); - -const path = require('path'); - -const env = process.env.NODE_ENV === 'production' ? 'production' : 'development'; - -const config = { - mode: env, - context: __dirname, - entry: { - index: path.join(__dirname, 'src/index.js'), - }, - target: 'node', - node: { - __dirname: false, - }, - output: { - path: path.join(__dirname, 'dist'), - filename: 'index.js', - libraryTarget: 'commonjs-module', - library: 'authorization', - }, - module: { - rules: [{ - test: /\.(js|jsx)$/, - use: ['babel-loader'], - }, - ], - }, - plugins: [ - new webpack.DefinePlugin({ - '.': '__dirname', - }), - new webpack.optimize.ModuleConcatenationPlugin(), - new ProgressBarPlugin(), - ], - resolve: { - modules: [ - path.join(__dirname, 'src'), - 'node_modules', - ], - }, - stats: { - colors: true, - }, - devtool: false, -}; - -module.exports = config; diff --git a/example/keycloak-cloudfront-portal/lambdaEdgeProxy.js b/example/keycloak-cloudfront-portal/lambdaEdgeProxy.js deleted file mode 100644 index a335c66..0000000 --- a/example/keycloak-cloudfront-portal/lambdaEdgeProxy.js +++ /dev/null @@ -1,87 +0,0 @@ -import { lambda } from 'lambda-edge-example'; - -function splitUrl(url) { - if (url.indexOf('?') <= 0) { - return { - uri: url, - querystring: '', - }; - } - const querystring = url.substr(url.indexOf('?') + 1, url.length); - return { - uri: url.substr(0, url.indexOf('?')), - querystring, - }; -} - -function transformRequest(req) { - const urlQuery = splitUrl(req.originalUrl); - const headers = {}; - Object.keys(req.headers).forEach((headerName) => { - const headerValue = req.headers[headerName]; - headers[headerName] = [{ - key: headerName, - value: headerValue, - }]; - }); - headers.referer = [ - { - key: 'Referer', - value: `http://${req.headers.host}`, - }, - ]; - return { - localhost: true, - Records: [ - { - cf: { - config: { - distributionId: 'EXAMPLE', - eventType: 'local-request', - }, - request: { - uri: urlQuery.uri, - querystring: urlQuery.querystring, - method: req.method, - clientIp: '2001:cdba::3257:9652', - headers, - }, - }, - }, - ], - }; -} - -function transformResponse(response, res, next) { - if (response.clientIp && response.method) { - next(); - } else { - const resHeader = res.status(response.status); - if (response.headers) { - Object.keys(response.headers).forEach((headerName) => { - const headers = {}; - response.headers[headerName].forEach((hn) => { - if (headers[hn.key]) { - headers[hn.key].push(hn.value); - } else { - headers[hn.key] = [hn.value]; - } - }); - Object.keys(headers).forEach((hn) => { - resHeader.set(hn, headers[hn]); - }); - }); - } - res.send(response.body); - } -} - -module.exports.middleware = async (req, res, next) => { - const cb = function callback(error, r) { - if (error) { - throw new Error(error); - } - transformResponse(r, res, next); - }; - await lambda(transformRequest(req), {}, cb); -}; diff --git a/example/keycloak-cloudfront-portal/package.json b/example/keycloak-cloudfront-portal/package.json deleted file mode 100644 index 0ac731f..0000000 --- a/example/keycloak-cloudfront-portal/package.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "name": "keycloak-cloudfront-portal", - "version": "1.0.0", - "description": "## 1. Start Keycloak", - "main": "index.js", - "scripts": { - "build": "NODE_ENV=production webpack --bail --config webpack.config.babel.js", - "start": "webpack serve --config webpack.config.babel.js", - "lint": "eslint --quiet --ext .js lambdaEdgeProxy.js && eslint --quiet --ext .js src lambda-edge-example/index.js lambda-edge-example/src keycloak-cloudfront-cdk/index.js", - "lint:fix": "eslint --fix --quiet --ext .js lambdaEdgeProxy.js && eslint --fix --quiet --ext .js src lambda-edge-example/index.js lambda-edge-example/src keycloak-cloudfront-cdk/index.js", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "vzakharchenko", - "license": "Apache-2.0", - "browser": { - "crypto": false - }, - "devDependencies": { - "@babel/core": "^7.14.0", - "@babel/plugin-proposal-class-properties": "^7.13.0", - "@babel/plugin-proposal-decorators": "^7.13.15", - "@babel/plugin-proposal-do-expressions": "^7.14.0", - "@babel/plugin-proposal-export-default-from": "^7.12.13", - "@babel/plugin-proposal-function-sent": "^7.12.13", - "@babel/plugin-proposal-object-rest-spread": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-partial-application": "^7.12.13", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-object-assign": "^7.12.13", - "@babel/plugin-transform-react-jsx": "^7.13.12", - "@babel/plugin-transform-runtime": "^7.13.15", - "@babel/preset-env": "^7.14.0", - "@babel/preset-flow": "^7.13.13", - "@babel/preset-react": "^7.13.13", - "@babel/register": "^7.13.16", - "@material-ui/styles": "^4.11.4", - "babel-eslint": "^10.1.0", - "babel-loader": "^8.2.2", - "babel-plugin-dynamic-import-node": "^2.3.3", - "css-loader": "^5.2.4", - "eslint": "^7.25.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-jsx-a11y": "^6.4.1", - "eslint-plugin-react": "^7.23.2", - "file-loader": "^6.2.0", - "html-webpack-plugin": "^5.3.1", - "lambda-edge-example": "./lambda-edge-example", - "progress-bar-webpack-plugin": "^2.1.0", - "style-loader": "^2.0.0", - "webpack": "^5.36.2", - "webpack-cli": "^4.6.0", - "webpack-dev-server": "^3.11.2" - }, - "dependencies": { - "@babel/polyfill": "^7.10.1", - "@material-ui/core": "^4.11.4", - "@material-ui/icons": "^4.11.2", - "axios": "^0.21.1", - "browserify": "^17.0.0", - "crypto-js": "^4.0.0", - "js-cookie": "^2.2.1", - "keycloak-lambda-cloudfront-ui": "^0.1.6", - "mobx-utils": "^6.0.4", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "stream": "*", - "typeface-roboto": "1.1.13", - "yallist": "^4.0.0" - } -} diff --git a/example/keycloak-cloudfront-portal/portal-realm.json b/example/keycloak-cloudfront-portal/portal-realm.json deleted file mode 100644 index 08f2b3d..0000000 --- a/example/keycloak-cloudfront-portal/portal-realm.json +++ /dev/null @@ -1,1762 +0,0 @@ -{ - "id": "portal", - "realm": "portal", - "notBefore": 0, - "revokeRefreshToken": false, - "refreshTokenMaxReuse": 0, - "accessTokenLifespan": 300, - "accessTokenLifespanForImplicitFlow": 900, - "ssoSessionIdleTimeout": 1800, - "ssoSessionMaxLifespan": 36000, - "ssoSessionIdleTimeoutRememberMe": 0, - "ssoSessionMaxLifespanRememberMe": 0, - "offlineSessionIdleTimeout": 2592000, - "offlineSessionMaxLifespanEnabled": false, - "offlineSessionMaxLifespan": 5184000, - "clientSessionIdleTimeout": 0, - "clientSessionMaxLifespan": 0, - "accessCodeLifespan": 60, - "accessCodeLifespanUserAction": 300, - "accessCodeLifespanLogin": 1800, - "actionTokenGeneratedByAdminLifespan": 43200, - "actionTokenGeneratedByUserLifespan": 300, - "enabled": true, - "sslRequired": "external", - "registrationAllowed": false, - "registrationEmailAsUsername": false, - "rememberMe": false, - "verifyEmail": false, - "loginWithEmailAllowed": true, - "duplicateEmailsAllowed": false, - "resetPasswordAllowed": false, - "editUsernameAllowed": false, - "bruteForceProtected": false, - "permanentLockout": false, - "maxFailureWaitSeconds": 900, - "minimumQuickLoginWaitSeconds": 60, - "waitIncrementSeconds": 60, - "quickLoginCheckMilliSeconds": 1000, - "maxDeltaTimeSeconds": 43200, - "failureFactor": 30, - "defaultRoles": [ - "uma_authorization", - "offline_access" - ], - "requiredCredentials": [ - "password" - ], - "otpPolicyType": "totp", - "otpPolicyAlgorithm": "HmacSHA1", - "otpPolicyInitialCounter": 0, - "otpPolicyDigits": 6, - "otpPolicyLookAheadWindow": 1, - "otpPolicyPeriod": 30, - "otpSupportedApplications": [ - "FreeOTP", - "Google Authenticator" - ], - "webAuthnPolicyRpEntityName": "keycloak", - "webAuthnPolicySignatureAlgorithms": [ - "ES256" - ], - "webAuthnPolicyRpId": "", - "webAuthnPolicyAttestationConveyancePreference": "not specified", - "webAuthnPolicyAuthenticatorAttachment": "not specified", - "webAuthnPolicyRequireResidentKey": "not specified", - "webAuthnPolicyUserVerificationRequirement": "not specified", - "webAuthnPolicyCreateTimeout": 0, - "webAuthnPolicyAvoidSameAuthenticatorRegister": false, - "webAuthnPolicyAcceptableAaguids": [], - "webAuthnPolicyPasswordlessRpEntityName": "keycloak", - "webAuthnPolicyPasswordlessSignatureAlgorithms": [ - "ES256" - ], - "webAuthnPolicyPasswordlessRpId": "", - "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified", - "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified", - "webAuthnPolicyPasswordlessRequireResidentKey": "not specified", - "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified", - "webAuthnPolicyPasswordlessCreateTimeout": 0, - "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false, - "webAuthnPolicyPasswordlessAcceptableAaguids": [], - "users" : [ - { - "username" : "user", - "enabled": true, - "email" : "user@example.com", - "firstName": "user", - "lastName": "Example", - "credentials" : [ - { "type" : "password", - "value" : "user" } - ], - "clientRoles": { - "account": ["view-profile", "manage-account"] - } - }, - { - "username" : "user1", - "enabled": true, - "email" : "user1@example.com", - "firstName": "user1", - "lastName": "Example", - "credentials" : [ - { "type" : "password", - "value" : "user1" } - ], - "clientRoles": { - "account": ["view-profile", "manage-account"] - } - }, - { - "username" : "user2", - "enabled": true, - "email" : "user2@example.com", - "firstName": "user2", - "lastName": "Example", - "credentials" : [ - { "type" : "password", - "value" : "user1" } - ], - "clientRoles": { - "account": ["view-profile", "manage-account"] - } - } - ], - "scopeMappings": [ - { - "clientScope": "offline_access", - "roles": [ - "offline_access" - ] - } - ], - "clientScopeMappings": { - "account": [ - { - "client": "account-console", - "roles": [ - "manage-account" - ] - } - ] - }, - "clients": [ - { - "id": "4210e4bb-fdc5-44f9-a973-24afd0169c14", - "clientId": "account", - "name": "${client_account}", - "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/portal/account/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "defaultRoles": [ - "view-profile", - "manage-account" - ], - "redirectUris": [ - "/realms/portal/account/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "cd0e72bc-e3aa-4e25-beb2-5ae97e285520", - "clientId": "account-console", - "name": "${client_account-console}", - "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/portal/account/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [ - "/realms/portal/account/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "pkce.code.challenge.method": "S256" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "protocolMappers": [ - { - "id": "4251867b-c3e9-4a96-b879-181cbb63240a", - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": {} - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "b21de2ce-a7ef-4cad-9835-d6e7bed26fa7", - "clientId": "admin-cli", - "name": "${client_admin-cli}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": false, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "a44ecbd7-ccf1-4b0c-b4df-1610d6a32df6", - "clientId": "broker", - "name": "${client_broker}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "42df1e6b-9e25-4378-b089-31c1b99f9510", - "clientId": "portal-ui", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "ece2012c-fc01-4dca-b50b-f898c9c6c811", - "redirectUris": [ - "*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "saml.assertion.signature": "false", - "saml.force.post.binding": "false", - "saml.multivalued.roles": "false", - "saml.encrypt": "false", - "saml.server.signature": "false", - "saml.server.signature.keyinfo.ext": "false", - "exclude.session.state.from.auth.response": "false", - "saml_force_name_id_format": "false", - "saml.client.signature": "false", - "tls.client.certificate.bound.access.tokens": "false", - "saml.authnstatement": "false", - "display.on.consent.screen": "false", - "saml.onetimeuse.condition": "false" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "cb1553b9-2b53-40c0-828c-9f061ec7f8c9", - "clientId": "realm-management", - "name": "${client_realm-management}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": true, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "c469a94b-1951-480e-95e8-4a01039db89e", - "clientId": "security-admin-console", - "name": "${client_security-admin-console}", - "rootUrl": "${authAdminUrl}", - "baseUrl": "/admin/portal/console/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [ - "/admin/portal/console/*" - ], - "webOrigins": [ - "+" - ], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "pkce.code.challenge.method": "S256" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "protocolMappers": [ - { - "id": "fb06849a-cfcf-4e75-b2a5-ad34339a5615", - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - } - ], - "clientScopes": [ - { - "id": "d3b6fe86-235c-4d73-8d95-dd53593635b1", - "name": "address", - "description": "OpenID Connect built-in scope: address", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${addressScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "e8a3f259-63b0-4000-b7e3-1cbb99c4d2db", - "name": "address", - "protocol": "openid-connect", - "protocolMapper": "oidc-address-mapper", - "consentRequired": false, - "config": { - "user.attribute.formatted": "formatted", - "user.attribute.country": "country", - "user.attribute.postal_code": "postal_code", - "userinfo.token.claim": "true", - "user.attribute.street": "street", - "id.token.claim": "true", - "user.attribute.region": "region", - "access.token.claim": "true", - "user.attribute.locality": "locality" - } - } - ] - }, - { - "id": "f8b8e752-b777-40f4-a500-7c21788b2233", - "name": "email", - "description": "OpenID Connect built-in scope: email", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${emailScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "85a0fa6f-9b81-464d-9e17-839cffb4d49c", - "name": "email", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "email", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email", - "jsonType.label": "String" - } - }, - { - "id": "1c06fd35-7f16-47b1-bfab-c519d24d399e", - "name": "email verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "emailVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email_verified", - "jsonType.label": "boolean" - } - } - ] - }, - { - "id": "b5f62f31-57fe-41ca-8ffb-b3ccce27df59", - "name": "microprofile-jwt", - "description": "Microprofile - JWT built-in scope", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "false" - }, - "protocolMappers": [ - { - "id": "308adaeb-3858-424c-a914-e06f1a634a63", - "name": "upn", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "username", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "upn", - "jsonType.label": "String" - } - }, - { - "id": "30970f53-93cc-4b48-b2ef-dc80811b6c30", - "name": "groups", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", - "consentRequired": false, - "config": { - "multivalued": "true", - "user.attribute": "foo", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "groups", - "jsonType.label": "String" - } - } - ] - }, - { - "id": "189a5bdb-5454-4fb8-bb2b-70f6c4d4c698", - "name": "offline_access", - "description": "OpenID Connect built-in scope: offline_access", - "protocol": "openid-connect", - "attributes": { - "consent.screen.text": "${offlineAccessScopeConsentText}", - "display.on.consent.screen": "true" - } - }, - { - "id": "b148f888-01b6-46af-bba5-9c85a129511e", - "name": "phone", - "description": "OpenID Connect built-in scope: phone", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${phoneScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "40066721-fcbf-4bca-af8d-bad4b2bc74af", - "name": "phone number", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "phoneNumber", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number", - "jsonType.label": "String" - } - }, - { - "id": "69241f93-460e-4268-bfb6-cb32fd57b137", - "name": "phone number verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "phoneNumberVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number_verified", - "jsonType.label": "boolean" - } - } - ] - }, - { - "id": "d613c1b3-905b-4d14-9c81-6dc89f0a42fc", - "name": "profile", - "description": "OpenID Connect built-in scope: profile", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${profileScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "75ee3589-5b18-4ecd-b99a-b1fc2143a850", - "name": "zoneinfo", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "zoneinfo", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "zoneinfo", - "jsonType.label": "String" - } - }, - { - "id": "5ddc55f9-8afd-4c17-931c-7f27b89f24be", - "name": "nickname", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "nickname", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "nickname", - "jsonType.label": "String" - } - }, - { - "id": "b1f9b309-e178-45d2-896a-ae7bad68d92f", - "name": "gender", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "gender", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "gender", - "jsonType.label": "String" - } - }, - { - "id": "aff24cad-92de-4749-a01a-0b12c3070768", - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - }, - { - "id": "f3aa0ac8-d9c5-4c8f-a823-b069e146fdda", - "name": "full name", - "protocol": "openid-connect", - "protocolMapper": "oidc-full-name-mapper", - "consentRequired": false, - "config": { - "id.token.claim": "true", - "access.token.claim": "true", - "userinfo.token.claim": "true" - } - }, - { - "id": "998b8fe9-1f3a-45d0-b5f4-6d75a2870128", - "name": "profile", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "profile", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "profile", - "jsonType.label": "String" - } - }, - { - "id": "0e4269bb-aa72-421d-92cb-1ba2bdb6912d", - "name": "website", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "website", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "website", - "jsonType.label": "String" - } - }, - { - "id": "eba794ab-19af-4f0e-b32c-8aac4e8a76a3", - "name": "birthdate", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "birthdate", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "birthdate", - "jsonType.label": "String" - } - }, - { - "id": "0ab5c9e3-7446-4cec-aa85-2088c8f42a86", - "name": "picture", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "picture", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "picture", - "jsonType.label": "String" - } - }, - { - "id": "19fc5fde-59cc-453d-87a5-c1e1202bf45c", - "name": "family name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "lastName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "family_name", - "jsonType.label": "String" - } - }, - { - "id": "1ef37431-65cd-4366-9b3e-84d5d5c89e5b", - "name": "updated at", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "updatedAt", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "updated_at", - "jsonType.label": "String" - } - }, - { - "id": "ecf0241d-e2d4-4681-92bc-e9b33b5558ba", - "name": "username", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "username", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "preferred_username", - "jsonType.label": "String" - } - }, - { - "id": "407594dc-e757-4cfa-a909-a8f16a1eb728", - "name": "given name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "firstName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "given_name", - "jsonType.label": "String" - } - }, - { - "id": "ed2a0866-fac6-43ed-b930-e470e6b9ab1e", - "name": "middle name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "middleName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "middle_name", - "jsonType.label": "String" - } - } - ] - }, - { - "id": "752f869d-93ed-47e8-9009-20566bb2a2db", - "name": "role_list", - "description": "SAML role list", - "protocol": "saml", - "attributes": { - "consent.screen.text": "${samlRoleListScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - "id": "8ebe04ec-6024-436d-9ac4-31d1e9fb6fd5", - "name": "role list", - "protocol": "saml", - "protocolMapper": "saml-role-list-mapper", - "consentRequired": false, - "config": { - "single": "false", - "attribute.nameformat": "Basic", - "attribute.name": "Role" - } - } - ] - }, - { - "id": "0733efe9-0bfb-4704-a7ed-75965f0b7722", - "name": "roles", - "description": "OpenID Connect scope for add user roles to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "true", - "consent.screen.text": "${rolesScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "4e9fdab2-4958-47fa-9091-874a548ea0b5", - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": {} - }, - { - "id": "074420ba-44c1-4bd0-951e-2d03af71e8ad", - "name": "client roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-client-role-mapper", - "consentRequired": false, - "config": { - "multivalued": "true", - "user.attribute": "foo", - "access.token.claim": "true", - "claim.name": "resource_access.${client_id}.roles", - "jsonType.label": "String" - } - }, - { - "id": "249d0cea-907f-4444-b333-8ff598700c3a", - "name": "realm roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", - "consentRequired": false, - "config": { - "multivalued": "true", - "user.attribute": "foo", - "access.token.claim": "true", - "claim.name": "realm_access.roles", - "jsonType.label": "String" - } - } - ] - }, - { - "id": "4059bbbf-30fe-4ff3-be9e-260146a38035", - "name": "web-origins", - "description": "OpenID Connect scope for add allowed web origins to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "false", - "consent.screen.text": "" - }, - "protocolMappers": [ - { - "id": "12c43b2f-e9fb-481d-951b-5d0ccc83ea0d", - "name": "allowed web origins", - "protocol": "openid-connect", - "protocolMapper": "oidc-allowed-origins-mapper", - "consentRequired": false, - "config": {} - } - ] - } - ], - "defaultDefaultClientScopes": [ - "roles", - "web-origins", - "role_list", - "profile", - "email" - ], - "defaultOptionalClientScopes": [ - "offline_access", - "phone", - "microprofile-jwt", - "address" - ], - "browserSecurityHeaders": { - "contentSecurityPolicyReportOnly": "", - "xContentTypeOptions": "nosniff", - "xRobotsTag": "none", - "xFrameOptions": "SAMEORIGIN", - "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", - "xXSSProtection": "1; mode=block", - "strictTransportSecurity": "max-age=31536000; includeSubDomains" - }, - "smtpServer": {}, - "eventsEnabled": false, - "eventsListeners": [ - "jboss-logging" - ], - "enabledEventTypes": [], - "adminEventsEnabled": false, - "adminEventsDetailsEnabled": false, - "components": { - "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ - { - "id": "40dd6da9-76d5-4702-b0e4-a2fc72a99eaa", - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - "id": "d4589a33-7de4-4636-bdd4-78c323adf4ae", - "name": "Trusted Hosts", - "providerId": "trusted-hosts", - "subType": "anonymous", - "subComponents": {}, - "config": { - "host-sending-registration-request-must-match": [ - "true" - ], - "client-uris-must-match": [ - "true" - ] - } - }, - { - "id": "1ef3f536-1207-4467-be10-94eb5e2cbd75", - "name": "Max Clients Limit", - "providerId": "max-clients", - "subType": "anonymous", - "subComponents": {}, - "config": { - "max-clients": [ - "200" - ] - } - }, - { - "id": "3e8958ac-e062-4867-9089-2d3f80a412ec", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "oidc-usermodel-attribute-mapper", - "oidc-full-name-mapper", - "saml-user-attribute-mapper", - "oidc-usermodel-property-mapper", - "saml-user-property-mapper", - "oidc-address-mapper", - "saml-role-list-mapper", - "oidc-sha256-pairwise-sub-mapper" - ] - } - }, - { - "id": "55ba9219-c8bf-4034-8c5a-1a3464d8c6f5", - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - "id": "ef9bd5b2-27e0-48b4-bcae-082da0cc46a4", - "name": "Full Scope Disabled", - "providerId": "scope", - "subType": "anonymous", - "subComponents": {}, - "config": {} - }, - { - "id": "c6ec44ad-2a40-4b63-824c-e037168b6006", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "saml-user-attribute-mapper", - "oidc-full-name-mapper", - "saml-role-list-mapper", - "oidc-usermodel-attribute-mapper", - "saml-user-property-mapper", - "oidc-address-mapper", - "oidc-sha256-pairwise-sub-mapper", - "oidc-usermodel-property-mapper" - ] - } - }, - { - "id": "4694d39a-86b6-4684-9f3f-fc3394f32a4f", - "name": "Consent Required", - "providerId": "consent-required", - "subType": "anonymous", - "subComponents": {}, - "config": {} - } - ], - "org.keycloak.keys.KeyProvider": [ - { - "id": "cabe08fe-79d1-40a7-8206-9a49d9b370be", - "name": "aes-generated", - "providerId": "aes-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - "id": "177e5bb4-d323-420e-b7ea-20400ae14dc2", - "name": "rsa-generated", - "providerId": "rsa-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - "id": "4f5995c3-c337-4b79-ad51-cc564766230e", - "name": "hmac-generated", - "providerId": "hmac-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "HS256" - ] - } - } - ] - }, - "internationalizationEnabled": false, - "supportedLocales": [], - "authenticationFlows": [ - { - "id": "d3f2373d-d7d4-4487-8a9b-cffc3a31d72a", - "alias": "Account verification options", - "description": "Method with which to verity the existing account", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-email-verification", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 20, - "flowAlias": "Verify Existing Account by Re-authentication", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "45a3c9f4-6add-41a9-9bb0-ed9e1db9e98c", - "alias": "Authentication Options", - "description": "Authentication options.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "basic-auth", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "basic-auth-otp", - "requirement": "DISABLED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "49404361-1eb9-421f-921e-67ac8f1c90de", - "alias": "Browser - Conditional OTP", - "description": "Flow to determine if the OTP is required for the authentication", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "ef0e4d77-e67c-43ba-a7c6-5506601ec691", - "alias": "Direct Grant - Conditional OTP", - "description": "Flow to determine if the OTP is required for the authentication", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "direct-grant-validate-otp", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "720dd47e-c72f-4030-a42c-6ad85147afce", - "alias": "First broker login - Conditional OTP", - "description": "Flow to determine if the OTP is required for the authentication", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "9b0e4a0e-ae53-4048-9b0a-017239580711", - "alias": "Handle Existing Account", - "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-confirm-link", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "REQUIRED", - "priority": 20, - "flowAlias": "Account verification options", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "26dd01a4-4a43-4313-80a8-c03352792dde", - "alias": "Reset - Conditional OTP", - "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-otp", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "d80aee43-36f4-49ca-bd7b-ddedd28d9ce9", - "alias": "User creation or linking", - "description": "Flow for the existing/non-existing user alternatives", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticatorConfig": "create unique user config", - "authenticator": "idp-create-user-if-unique", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 20, - "flowAlias": "Handle Existing Account", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "3861e171-b5f3-47b2-844a-e1d4d20ad821", - "alias": "Verify Existing Account by Re-authentication", - "description": "Reauthentication of existing account", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 20, - "flowAlias": "First broker login - Conditional OTP", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "3a9df5dc-0092-417b-9f90-6f61f05e0090", - "alias": "browser", - "description": "browser based authentication", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-cookie", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "identity-provider-redirector", - "requirement": "ALTERNATIVE", - "priority": 25, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 30, - "flowAlias": "forms", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "d30e6ea5-8c01-43b0-a1cc-79e40bbbd7e1", - "alias": "clients", - "description": "Base authentication for clients", - "providerId": "client-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "client-secret", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-jwt", - "requirement": "ALTERNATIVE", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-secret-jwt", - "requirement": "ALTERNATIVE", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-x509", - "requirement": "ALTERNATIVE", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "70957643-48d8-4dec-80f7-d2627828f9d8", - "alias": "direct grant", - "description": "OpenID Connect Resource Owner Grant", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "direct-grant-validate-username", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "direct-grant-validate-password", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 30, - "flowAlias": "Direct Grant - Conditional OTP", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "fc6943c8-b790-4589-a523-f197ce21d04b", - "alias": "docker auth", - "description": "Used by Docker clients to authenticate against the IDP", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "docker-http-basic-authenticator", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "ca8d0e62-0be8-4d60-8383-bf8920e1fc62", - "alias": "first broker login", - "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticatorConfig": "review profile config", - "authenticator": "idp-review-profile", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "REQUIRED", - "priority": 20, - "flowAlias": "User creation or linking", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "3ac93a88-cb6e-457a-8658-631fd8684bc2", - "alias": "forms", - "description": "Username, password, otp and other auth forms.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 20, - "flowAlias": "Browser - Conditional OTP", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "e89d7882-f002-450b-8267-0d5e32727dd7", - "alias": "http challenge", - "description": "An authentication flow based on challenge-response HTTP Authentication Schemes", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "no-cookie-redirect", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "REQUIRED", - "priority": 20, - "flowAlias": "Authentication Options", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "506022fa-9c17-4b24-bcff-a82716fe2089", - "alias": "registration", - "description": "registration flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-page-form", - "requirement": "REQUIRED", - "priority": 10, - "flowAlias": "registration form", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "c1fbfe2a-15dc-495a-8553-43d3fa58a43b", - "alias": "registration form", - "description": "registration form", - "providerId": "form-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-user-creation", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-profile-action", - "requirement": "REQUIRED", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-password-action", - "requirement": "REQUIRED", - "priority": 50, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-recaptcha-action", - "requirement": "DISABLED", - "priority": 60, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "a63cef51-f789-4908-8b70-d43bd7298a60", - "alias": "reset credentials", - "description": "Reset credentials for a user if they forgot their password or something", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "reset-credentials-choose-user", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-credential-email", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-password", - "requirement": "REQUIRED", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 40, - "flowAlias": "Reset - Conditional OTP", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "b552a368-8161-4527-8626-d2a84a5c4d38", - "alias": "saml ecp", - "description": "SAML ECP Profile Authentication Flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "http-basic-authenticator", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - } - ], - "authenticatorConfig": [ - { - "id": "39c11bbd-02ef-4a55-b4e4-eb6207cd4643", - "alias": "create unique user config", - "config": { - "require.password.update.after.registration": "false" - } - }, - { - "id": "4399da5c-1985-4d52-91e8-435cb722230d", - "alias": "review profile config", - "config": { - "update.profile.on.first.login": "missing" - } - } - ], - "requiredActions": [ - { - "alias": "CONFIGURE_TOTP", - "name": "Configure OTP", - "providerId": "CONFIGURE_TOTP", - "enabled": true, - "defaultAction": false, - "priority": 10, - "config": {} - }, - { - "alias": "terms_and_conditions", - "name": "Terms and Conditions", - "providerId": "terms_and_conditions", - "enabled": false, - "defaultAction": false, - "priority": 20, - "config": {} - }, - { - "alias": "UPDATE_PASSWORD", - "name": "Update Password", - "providerId": "UPDATE_PASSWORD", - "enabled": true, - "defaultAction": false, - "priority": 30, - "config": {} - }, - { - "alias": "UPDATE_PROFILE", - "name": "Update Profile", - "providerId": "UPDATE_PROFILE", - "enabled": true, - "defaultAction": false, - "priority": 40, - "config": {} - }, - { - "alias": "VERIFY_EMAIL", - "name": "Verify Email", - "providerId": "VERIFY_EMAIL", - "enabled": true, - "defaultAction": false, - "priority": 50, - "config": {} - }, - { - "alias": "update_user_locale", - "name": "Update User Locale", - "providerId": "update_user_locale", - "enabled": true, - "defaultAction": false, - "priority": 1000, - "config": {} - } - ], - "browserFlow": "browser", - "registrationFlow": "registration", - "directGrantFlow": "direct grant", - "resetCredentialsFlow": "reset credentials", - "clientAuthenticationFlow": "clients", - "dockerAuthenticationFlow": "docker auth", - "attributes": {}, - "keycloakVersion": "10.0.1", - "userManagedAccessAllowed": false -} \ No newline at end of file diff --git a/example/keycloak-cloudfront-portal/securityRealm1.json b/example/keycloak-cloudfront-portal/securityRealm1.json deleted file mode 100644 index 9242901..0000000 --- a/example/keycloak-cloudfront-portal/securityRealm1.json +++ /dev/null @@ -1,2317 +0,0 @@ -{ - "id": "securityRealm1", - "realm": "securityRealm1", - "notBefore": 0, - "revokeRefreshToken": false, - "refreshTokenMaxReuse": 0, - "accessTokenLifespan": 300, - "accessTokenLifespanForImplicitFlow": 900, - "ssoSessionIdleTimeout": 1800, - "ssoSessionMaxLifespan": 36000, - "ssoSessionIdleTimeoutRememberMe": 0, - "ssoSessionMaxLifespanRememberMe": 0, - "offlineSessionIdleTimeout": 2592000, - "offlineSessionMaxLifespanEnabled": false, - "offlineSessionMaxLifespan": 5184000, - "clientSessionIdleTimeout": 0, - "clientSessionMaxLifespan": 0, - "accessCodeLifespan": 60, - "accessCodeLifespanUserAction": 300, - "accessCodeLifespanLogin": 1800, - "actionTokenGeneratedByAdminLifespan": 43200, - "actionTokenGeneratedByUserLifespan": 300, - "enabled": true, - "sslRequired": "external", - "registrationAllowed": false, - "registrationEmailAsUsername": false, - "rememberMe": false, - "verifyEmail": false, - "loginWithEmailAllowed": true, - "duplicateEmailsAllowed": false, - "resetPasswordAllowed": false, - "editUsernameAllowed": false, - "bruteForceProtected": false, - "permanentLockout": false, - "maxFailureWaitSeconds": 900, - "minimumQuickLoginWaitSeconds": 60, - "waitIncrementSeconds": 60, - "quickLoginCheckMilliSeconds": 1000, - "maxDeltaTimeSeconds": 43200, - "failureFactor": 30, - "roles": { - "realm": [ - { - "name": "securityRealmRole", - "composite": false, - "clientRole": false, - "containerId": "securityRealm1", - "attributes": {} - }, - { - - "name": "offline_access", - "description": "${role_offline-access}", - "composite": false, - "clientRole": false, - "containerId": "securityRealm1", - "attributes": {} - }, - { - - "name": "uma_authorization", - "description": "${role_uma_authorization}", - "composite": false, - "clientRole": false, - "containerId": "securityRealm1", - "attributes": {} - } - ], - "client": { - "realm-management": [ - { - - "name": "query-clients", - "description": "${role_query-clients}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "query-groups", - "description": "${role_query-groups}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "realm-admin", - "description": "${role_realm-admin}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-clients", - "query-groups", - "view-events", - "query-realms", - "manage-realm", - "view-authorization", - "impersonation", - "manage-users", - "create-client", - "view-identity-providers", - "manage-identity-providers", - "manage-clients", - "query-users", - "view-users", - "manage-events", - "view-realm", - "manage-authorization", - "view-clients" - ] - } - }, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "view-events", - "description": "${role_view-events}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "query-realms", - "description": "${role_query-realms}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "manage-realm", - "description": "${role_manage-realm}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "view-authorization", - "description": "${role_view-authorization}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "impersonation", - "description": "${role_impersonation}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "manage-users", - "description": "${role_manage-users}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "create-client", - "description": "${role_create-client}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "view-identity-providers", - "description": "${role_view-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "manage-clients", - "description": "${role_manage-clients}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "manage-identity-providers", - "description": "${role_manage-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "query-users", - "description": "${role_query-users}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "view-users", - "description": "${role_view-users}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-groups", - "query-users" - ] - } - }, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "manage-events", - "description": "${role_manage-events}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "view-realm", - "description": "${role_view-realm}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "view-clients", - "description": "${role_view-clients}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-clients" - ] - } - }, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "manage-authorization", - "description": "${role_manage-authorization}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - } - ], - "security-admin-console": [], - "securityRealmClient": [ - { - - "name": "uma_protection", - "composite": false, - "clientRole": true, - "containerId": "2df50633-618d-41d9-961d-68470cfd2dc4", - "attributes": {} - } - ], - "admin-cli": [], - "account-console": [], - "broker": [ - { - - "name": "read-token", - "description": "${role_read-token}", - "composite": false, - "clientRole": true, - "containerId": "c45259be-d524-4e9e-93a5-68af7df7acf0", - "attributes": {} - } - ], - "account": [ - { - - "name": "manage-account-links", - "description": "${role_manage-account-links}", - "composite": false, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - }, - { - - "name": "view-applications", - "description": "${role_view-applications}", - "composite": false, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - }, - { - - "name": "view-consent", - "description": "${role_view-consent}", - "composite": false, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - }, - { - - "name": "view-profile", - "description": "${role_view-profile}", - "composite": false, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - }, - { - - "name": "manage-account", - "description": "${role_manage-account}", - "composite": true, - "composites": { - "client": { - "account": [ - "manage-account-links" - ] - } - }, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - }, - { - - "name": "manage-consent", - "description": "${role_manage-consent}", - "composite": true, - "composites": { - "client": { - "account": [ - "view-consent" - ] - } - }, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - } - ] - } - }, - "groups": [], - "defaultRoles": [ - "uma_authorization", - "offline_access" - ], - "requiredCredentials": [ - "password" - ], - "otpPolicyType": "totp", - "otpPolicyAlgorithm": "HmacSHA1", - "otpPolicyInitialCounter": 0, - "otpPolicyDigits": 6, - "otpPolicyLookAheadWindow": 1, - "otpPolicyPeriod": 30, - "otpSupportedApplications": [ - "FreeOTP", - "Google Authenticator" - ], - "webAuthnPolicyRpEntityName": "keycloak", - "webAuthnPolicySignatureAlgorithms": [ - "ES256" - ], - "webAuthnPolicyRpId": "", - "webAuthnPolicyAttestationConveyancePreference": "not specified", - "webAuthnPolicyAuthenticatorAttachment": "not specified", - "webAuthnPolicyRequireResidentKey": "not specified", - "webAuthnPolicyUserVerificationRequirement": "not specified", - "webAuthnPolicyCreateTimeout": 0, - "webAuthnPolicyAvoidSameAuthenticatorRegister": false, - "webAuthnPolicyAcceptableAaguids": [], - "webAuthnPolicyPasswordlessRpEntityName": "keycloak", - "webAuthnPolicyPasswordlessSignatureAlgorithms": [ - "ES256" - ], - "webAuthnPolicyPasswordlessRpId": "", - "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified", - "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified", - "webAuthnPolicyPasswordlessRequireResidentKey": "not specified", - "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified", - "webAuthnPolicyPasswordlessCreateTimeout": 0, - "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false, - "webAuthnPolicyPasswordlessAcceptableAaguids": [], - "users": [ - { - - "createdTimestamp": 1591013898421, - "username": "service-account-securityrealmclient", - "enabled": true, - "totp": false, - "emailVerified": false, - "serviceAccountClientId": "securityRealmClient", - "disableableCredentialTypes": [], - "requiredActions": [], - "realmRoles": [ - "offline_access", - "uma_authorization" - ], - "clientRoles": { - "securityRealmClient": [ - "uma_protection" - ], - "account": [ - "view-profile", - "manage-account" - ] - }, - "notBefore": 0, - "groups": [] - }, - { - "username" : "user", - "enabled": true, - "email" : "user@example.com", - "firstName": "user", - "lastName": "Example", - "realmRoles": [ "uma_authorization", "securityRealmRole" ], - "clientRoles": { - "account": ["view-profile", "manage-account"] - } - }, - { - "username" : "user1", - "enabled": true, - "email" : "user1@example.com", - "firstName": "user1", - "lastName": "Example", - "realmRoles": [ "uma_authorization", "securityRealmRole" ], - "clientRoles": { - "account": ["view-profile", "manage-account"] - } - } - ], - "scopeMappings": [ - { - "clientScope": "offline_access", - "roles": [ - "offline_access" - ] - } - ], - "clientScopeMappings": { - "account": [ - { - "client": "account-console", - "roles": [ - "manage-account" - ] - } - ] - }, - "clients": [ - { - - "clientId": "account", - "name": "${client_account}", - "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/securityRealm1/account/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "defaultRoles": [ - "view-profile", - "manage-account" - ], - "redirectUris": [ - "/realms/securityRealm1/account/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - - "clientId": "account-console", - "name": "${client_account-console}", - "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/securityRealm1/account/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [ - "/realms/securityRealm1/account/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "pkce.code.challenge.method": "S256" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "protocolMappers": [ - { - - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": {} - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - - "clientId": "admin-cli", - "name": "${client_admin-cli}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": false, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - - "clientId": "broker", - "name": "${client_broker}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - - "clientId": "realm-management", - "name": "${client_realm-management}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": true, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ] - }, - { - - "clientId": "security-admin-console", - "name": "${client_security-admin-console}", - "rootUrl": "${authAdminUrl}", - "baseUrl": "/admin/securityRealm1/console/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [ - "/admin/securityRealm1/console/*" - ], - "webOrigins": [ - "+" - ], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "pkce.code.challenge.method": "S256" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "protocolMappers": [ - { - - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - - "clientId": "securityRealmClient", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-jwt", - "secret": "**********", - "redirectUris": [ - "*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": true, - "authorizationServicesEnabled": true, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "saml.assertion.signature": "false", - "saml.force.post.binding": "false", - "saml.multivalued.roles": "false", - "saml.encrypt": "false", - "use.jwks.url": "true", - "saml.server.signature": "false", - "saml.server.signature.keyinfo.ext": "false", - "exclude.session.state.from.auth.response": "false", - "jwks.url": "http://localhost:9000/cert", - "saml_force_name_id_format": "false", - "saml.client.signature": "false", - "tls.client.certificate.bound.access.tokens": "false", - "saml.authnstatement": "false", - "display.on.consent.screen": "false", - "saml.onetimeuse.condition": "false" - }, - "authenticationFlowBindingOverrides": { - "browser": "2fb21a60-58bc-416c-9c2e-c6caf234f4e1" - }, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, - "protocolMappers": [ - { - - "name": "Client IP Address", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientAddress", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientAddress", - "jsonType.label": "String" - } - }, - { - - "name": "Client ID", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientId", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientId", - "jsonType.label": "String" - } - }, - { - - "name": "Client Host", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientHost", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientHost", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ], - "authorizationSettings": { - "allowRemoteResourceManagement": true, - "policyEnforcementMode": "ENFORCING", - "resources": [ - { - "name": "securityRealmResource", - "ownerManagedAccess": false, - "displayName": "securityRealm Resource", - "attributes": {}, - "uris": [] - } - ], - "policies": [ - { - "name": "securityRealm Polici", - "type": "role", - "logic": "POSITIVE", - "decisionStrategy": "UNANIMOUS", - "config": { - "roles": "[{\"id\":\"securityRealmRole\",\"required\":true}]" - } - }, - { - - "name": "securityRealm Permission", - "type": "resource", - "logic": "POSITIVE", - "decisionStrategy": "UNANIMOUS", - "config": { - "resources": "[\"securityRealmResource\"]", - "applyPolicies": "[\"securityRealm Polici\"]" - } - } - ], - "scopes": [], - "decisionStrategy": "UNANIMOUS" - } - } - ], - "clientScopes": [ - { - "name": "address", - "description": "OpenID Connect built-in scope: address", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${addressScopeConsentText}" - }, - "protocolMappers": [ - { - "name": "address", - "protocol": "openid-connect", - "protocolMapper": "oidc-address-mapper", - "consentRequired": false, - "config": { - "user.attribute.formatted": "formatted", - "user.attribute.country": "country", - "user.attribute.postal_code": "postal_code", - "userinfo.token.claim": "true", - "user.attribute.street": "street", - "id.token.claim": "true", - "user.attribute.region": "region", - "access.token.claim": "true", - "user.attribute.locality": "locality" - } - } - ] - }, - { - "name": "email", - "description": "OpenID Connect built-in scope: email", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${emailScopeConsentText}" - }, - "protocolMappers": [ - { - "name": "email", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "email", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email", - "jsonType.label": "String" - } - }, - { - - "name": "email verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "emailVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email_verified", - "jsonType.label": "boolean" - } - } - ] - }, - { - "name": "microprofile-jwt", - "description": "Microprofile - JWT built-in scope", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "false" - }, - "protocolMappers": [ - { - - "name": "groups", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", - "consentRequired": false, - "config": { - "multivalued": "true", - "user.attribute": "foo", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "groups", - "jsonType.label": "String" - } - }, - { - "name": "upn", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "username", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "upn", - "jsonType.label": "String" - } - } - ] - }, - { - - "name": "offline_access", - "description": "OpenID Connect built-in scope: offline_access", - "protocol": "openid-connect", - "attributes": { - "consent.screen.text": "${offlineAccessScopeConsentText}", - "display.on.consent.screen": "true" - } - }, - { - - "name": "phone", - "description": "OpenID Connect built-in scope: phone", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${phoneScopeConsentText}" - }, - "protocolMappers": [ - { - - "name": "phone number", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "phoneNumber", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number", - "jsonType.label": "String" - } - }, - { - - "name": "phone number verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "phoneNumberVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number_verified", - "jsonType.label": "boolean" - } - } - ] - }, - { - - "name": "profile", - "description": "OpenID Connect built-in scope: profile", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${profileScopeConsentText}" - }, - "protocolMappers": [ - { - - "name": "username", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "username", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "preferred_username", - "jsonType.label": "String" - } - }, - { - - "name": "gender", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "gender", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "gender", - "jsonType.label": "String" - } - }, - { - - "name": "profile", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "profile", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "profile", - "jsonType.label": "String" - } - }, - { - - "name": "picture", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "picture", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "picture", - "jsonType.label": "String" - } - }, - { - - "name": "middle name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "middleName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "middle_name", - "jsonType.label": "String" - } - }, - { - - "name": "zoneinfo", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "zoneinfo", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "zoneinfo", - "jsonType.label": "String" - } - }, - { - - "name": "updated at", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "updatedAt", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "updated_at", - "jsonType.label": "String" - } - }, - { - - "name": "website", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "website", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "website", - "jsonType.label": "String" - } - }, - { - - "name": "nickname", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "nickname", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "nickname", - "jsonType.label": "String" - } - }, - { - - "name": "given name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "firstName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "given_name", - "jsonType.label": "String" - } - }, - { - - "name": "family name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "lastName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "family_name", - "jsonType.label": "String" - } - }, - { - - "name": "full name", - "protocol": "openid-connect", - "protocolMapper": "oidc-full-name-mapper", - "consentRequired": false, - "config": { - "id.token.claim": "true", - "access.token.claim": "true", - "userinfo.token.claim": "true" - } - }, - { - - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - }, - { - - "name": "birthdate", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "birthdate", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "birthdate", - "jsonType.label": "String" - } - } - ] - }, - { - - "name": "role_list", - "description": "SAML role list", - "protocol": "saml", - "attributes": { - "consent.screen.text": "${samlRoleListScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - - "name": "role list", - "protocol": "saml", - "protocolMapper": "saml-role-list-mapper", - "consentRequired": false, - "config": { - "single": "false", - "attribute.nameformat": "Basic", - "attribute.name": "Role" - } - } - ] - }, - { - - "name": "roles", - "description": "OpenID Connect scope for add user roles to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "true", - "consent.screen.text": "${rolesScopeConsentText}" - }, - "protocolMappers": [ - { - - "name": "realm roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", - "consentRequired": false, - "config": { - "user.attribute": "foo", - "access.token.claim": "true", - "claim.name": "realm_access.roles", - "jsonType.label": "String", - "multivalued": "true" - } - }, - { - - "name": "client roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-client-role-mapper", - "consentRequired": false, - "config": { - "user.attribute": "foo", - "access.token.claim": "true", - "claim.name": "resource_access.${client_id}.roles", - "jsonType.label": "String", - "multivalued": "true" - } - }, - { - - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": {} - } - ] - }, - { - - "name": "web-origins", - "description": "OpenID Connect scope for add allowed web origins to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "false", - "consent.screen.text": "" - }, - "protocolMappers": [ - { - - "name": "allowed web origins", - "protocol": "openid-connect", - "protocolMapper": "oidc-allowed-origins-mapper", - "consentRequired": false, - "config": {} - } - ] - } - ], - "defaultDefaultClientScopes": [ - "roles", - "email", - "web-origins", - "profile", - "role_list" - ], - "defaultOptionalClientScopes": [ - "phone", - "offline_access", - "microprofile-jwt", - "address" - ], - "browserSecurityHeaders": { - "contentSecurityPolicyReportOnly": "", - "xContentTypeOptions": "nosniff", - "xRobotsTag": "none", - "xFrameOptions": "SAMEORIGIN", - "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", - "xXSSProtection": "1; mode=block", - "strictTransportSecurity": "max-age=31536000; includeSubDomains" - }, - "smtpServer": {}, - "eventsEnabled": false, - "eventsListeners": [ - "jboss-logging" - ], - "enabledEventTypes": [], - "adminEventsEnabled": false, - "adminEventsDetailsEnabled": false, - "identityProviders": [ - { - "alias": "securityRealm1", - "internalId": "securityRealm1-Idp", - "providerId": "keycloak-oidc", - "enabled": true, - "updateProfileFirstLoginMode": "on", - "trustEmail": true, - "storeToken": true, - "addReadTokenRoleOnCreate": false, - "authenticateByDefault": false, - "linkOnly": false, - "firstBrokerLoginFlowAlias": "portal first broker login", - "config": { - "userInfoUrl": "http://127.0.0.1:8080/auth/realms/portal/protocol/openid-connect/userinfo", - "validateSignature": "true", - "clientId": "portal-ui", - "tokenUrl": "http://127.0.0.1:8080/auth/realms/portal/protocol/openid-connect/token", - "jwksUrl": "http://127.0.0.1:8080/auth/realms/portal/protocol/openid-connect/certs", - "issuer": "http://127.0.0.1:8080/auth/realms/portal", - "useJwksUrl": "true", - "authorizationUrl": "http://127.0.0.1:8080/auth/realms/portal/protocol/openid-connect/auth", - "clientAuthMethod": "client_secret_post", - "logoutUrl": "http://127.0.0.1:8080/auth/realms/portal/protocol/openid-connect/logout", - "syncMode": "IMPORT", - "clientSecret": "ece2012c-fc01-4dca-b50b-f898c9c6c811" - } - } - ], - "components": { - "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ - { - - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "oidc-usermodel-attribute-mapper", - "oidc-sha256-pairwise-sub-mapper", - "oidc-usermodel-property-mapper", - "saml-user-property-mapper", - "saml-user-attribute-mapper", - "oidc-address-mapper", - "oidc-full-name-mapper", - "saml-role-list-mapper" - ] - } - }, - { - - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - - "name": "Consent Required", - "providerId": "consent-required", - "subType": "anonymous", - "subComponents": {}, - "config": {} - }, - { - - "name": "Max Clients Limit", - "providerId": "max-clients", - "subType": "anonymous", - "subComponents": {}, - "config": { - "max-clients": [ - "200" - ] - } - }, - { - - "name": "Trusted Hosts", - "providerId": "trusted-hosts", - "subType": "anonymous", - "subComponents": {}, - "config": { - "host-sending-registration-request-must-match": [ - "true" - ], - "client-uris-must-match": [ - "true" - ] - } - }, - { - - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "oidc-sha256-pairwise-sub-mapper", - "saml-user-property-mapper", - "saml-user-attribute-mapper", - "saml-role-list-mapper", - "oidc-full-name-mapper", - "oidc-usermodel-property-mapper", - "oidc-usermodel-attribute-mapper", - "oidc-address-mapper" - ] - } - }, - { - - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - - "name": "Full Scope Disabled", - "providerId": "scope", - "subType": "anonymous", - "subComponents": {}, - "config": {} - } - ], - "org.keycloak.keys.KeyProvider": [ - { - - "name": "rsa-generated", - "providerId": "rsa-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - - "name": "hmac-generated", - "providerId": "hmac-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "HS256" - ] - } - }, - { - - "name": "aes-generated", - "providerId": "aes-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - } - ] - }, - "internationalizationEnabled": false, - "supportedLocales": [], - "authenticationFlows": [ - { - "id": "c0826cf4-6610-42e3-8c78-b33ab563ec60", - "alias": "Handle Existing Account", - "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-confirm-link", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "REQUIRED", - "priority": 20, - "flowAlias": "Handle Existing Account - Alternatives - 0", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "9fc0c79e-c609-4a81-8ad6-9f51e6839ce8", - "alias": "Handle Existing Account - Alternatives - 0", - "description": "Subflow of Handle Existing Account with alternative executions", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-email-verification", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 20, - "flowAlias": "Verify Existing Account by Re-authentication", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "7001651e-ac41-4a4b-8031-946cab0c7dcf", - "alias": "Verify Existing Account by Re-authentication", - "description": "Reauthentication of existing account", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 20, - "flowAlias": "Verify Existing Account by Re-authentication - auth-otp-form - Conditional", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "8896138d-bccb-4c8a-af02-a817187671e1", - "alias": "Verify Existing Account by Re-authentication - auth-otp-form - Conditional", - "description": "Flow to determine if the auth-otp-form authenticator should be used or not.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "8a11db23-2ddc-4613-b05e-46fa4e98c3ad", - "alias": "browser", - "description": "browser based authentication", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-cookie", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "identity-provider-redirector", - "requirement": "ALTERNATIVE", - "priority": 25, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 30, - "flowAlias": "forms", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "1884ec82-571b-40cb-bb08-316f5e2d38af", - "alias": "clients", - "description": "Base authentication for clients", - "providerId": "client-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "client-secret", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-jwt", - "requirement": "ALTERNATIVE", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-secret-jwt", - "requirement": "ALTERNATIVE", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-x509", - "requirement": "ALTERNATIVE", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "3aacc6c8-233f-4ad6-bd64-35512bcdc0fb", - "alias": "direct grant", - "description": "OpenID Connect Resource Owner Grant", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "direct-grant-validate-username", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "direct-grant-validate-password", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 30, - "flowAlias": "direct grant - direct-grant-validate-otp - Conditional", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "4c510a06-360c-4f59-8935-004e0e5a341b", - "alias": "direct grant - direct-grant-validate-otp - Conditional", - "description": "Flow to determine if the direct-grant-validate-otp authenticator should be used or not.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "direct-grant-validate-otp", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "560f3d8a-6202-438e-8a15-0b06470d8157", - "alias": "docker auth", - "description": "Used by Docker clients to authenticate against the IDP", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "docker-http-basic-authenticator", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "fa4a5f8c-0fcf-46f6-857b-594d6478badf", - "alias": "first broker login", - "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticatorConfig": "review profile config", - "authenticator": "idp-review-profile", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "REQUIRED", - "priority": 20, - "flowAlias": "first broker login - Alternatives - 0", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "2f4222f0-6483-4e49-b200-e6070e3e1ae7", - "alias": "first broker login - Alternatives - 0", - "description": "Subflow of first broker login with alternative executions", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticatorConfig": "create unique user config", - "authenticator": "idp-create-user-if-unique", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 20, - "flowAlias": "Handle Existing Account", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "e2095d6a-80bf-479f-b134-993b270ce2fe", - "alias": "forms", - "description": "Username, password, otp and other auth forms.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 20, - "flowAlias": "forms - auth-otp-form - Conditional", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "a031da47-0393-44d7-a1d4-21d9243a7613", - "alias": "forms - auth-otp-form - Conditional", - "description": "Flow to determine if the auth-otp-form authenticator should be used or not.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "06b3ca50-b22b-4b9b-9b6b-b931fa8d9445", - "alias": "http challenge", - "description": "An authentication flow based on challenge-response HTTP Authentication Schemes", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "no-cookie-redirect", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "basic-auth", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "basic-auth-otp", - "requirement": "DISABLED", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "2fb21a60-58bc-416c-9c2e-c6caf234f4e1", - "alias": "portal browser", - "description": "browser based authentication", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": false, - "authenticationExecutions": [ - { - "authenticator": "auth-cookie", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticatorConfig": "securityRealm1", - "authenticator": "identity-provider-redirector", - "requirement": "REQUIRED", - "priority": 25, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "DISABLED", - "priority": 30, - "flowAlias": "portal browser forms", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "1ce18998-1c6d-4af6-b713-1419dc0a7780", - "alias": "portal browser forms", - "description": "Username, password, otp and other auth forms.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": false, - "authenticationExecutions": [ - { - "authenticator": "auth-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 20, - "flowAlias": "portal browser forms - auth-otp-form - Conditional", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "dfc17f6b-db78-4cfb-8da6-9b5d7c07dfe4", - "alias": "portal browser forms - auth-otp-form - Conditional", - "description": "Flow to determine if the auth-otp-form authenticator should be used or not.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": false, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "alias": "portal first broker login", - "description": "", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": false, - "authenticationExecutions": [ - { - "authenticator": "idp-create-user-if-unique", - "requirement": "ALTERNATIVE", - "priority": 0, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "idp-auto-link", - "requirement": "ALTERNATIVE", - "priority": 1, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "f70c886e-a329-4ee5-b621-e77bbac5a1fc", - "alias": "registration", - "description": "registration flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-page-form", - "requirement": "REQUIRED", - "priority": 10, - "flowAlias": "registration form", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "5f92d792-b7fd-44ce-9e86-af1b8065825e", - "alias": "registration form", - "description": "registration form", - "providerId": "form-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-user-creation", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-profile-action", - "requirement": "REQUIRED", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-password-action", - "requirement": "REQUIRED", - "priority": 50, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-recaptcha-action", - "requirement": "DISABLED", - "priority": 60, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "636b68b0-a51c-4d5c-900d-2009b923389f", - "alias": "reset credentials", - "description": "Reset credentials for a user if they forgot their password or something", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "reset-credentials-choose-user", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-credential-email", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-password", - "requirement": "REQUIRED", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 40, - "flowAlias": "reset credentials - reset-otp - Conditional", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "58b7f5b2-2e64-45ca-a37a-c77c62bd5763", - "alias": "reset credentials - reset-otp - Conditional", - "description": "Flow to determine if the reset-otp authenticator should be used or not.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-otp", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "a30cb687-5462-4a3d-8f96-8fe156ced242", - "alias": "saml ecp", - "description": "SAML ECP Profile Authentication Flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "http-basic-authenticator", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - } - ], - "authenticatorConfig": [ - { - "id": "7f5f2951-7060-44d7-8b72-acedcda6e5b4", - "alias": "create unique user config", - "config": { - "require.password.update.after.registration": "false" - } - }, - { - "id": "a7e617de-55aa-4717-8ec0-d5ed1b1d1131", - "alias": "review profile config", - "config": { - "update.profile.on.first.login": "missing" - } - }, - { - "id": "5e12a81e-443c-48ab-95a4-8193ff2dcf33", - "alias": "securityRealm1", - "config": { - "defaultProvider": "securityRealm1" - } - } - ], - "requiredActions": [ - { - "alias": "CONFIGURE_TOTP", - "name": "Configure OTP", - "providerId": "CONFIGURE_TOTP", - "enabled": true, - "defaultAction": false, - "priority": 10, - "config": {} - }, - { - "alias": "terms_and_conditions", - "name": "Terms and Conditions", - "providerId": "terms_and_conditions", - "enabled": false, - "defaultAction": false, - "priority": 20, - "config": {} - }, - { - "alias": "UPDATE_PASSWORD", - "name": "Update Password", - "providerId": "UPDATE_PASSWORD", - "enabled": true, - "defaultAction": false, - "priority": 30, - "config": {} - }, - { - "alias": "UPDATE_PROFILE", - "name": "Update Profile", - "providerId": "UPDATE_PROFILE", - "enabled": true, - "defaultAction": false, - "priority": 40, - "config": {} - }, - { - "alias": "VERIFY_EMAIL", - "name": "Verify Email", - "providerId": "VERIFY_EMAIL", - "enabled": true, - "defaultAction": false, - "priority": 50, - "config": {} - }, - { - "alias": "update_user_locale", - "name": "Update User Locale", - "providerId": "update_user_locale", - "enabled": true, - "defaultAction": false, - "priority": 1000, - "config": {} - } - ], - "browserFlow": "browser", - "registrationFlow": "registration", - "directGrantFlow": "direct grant", - "resetCredentialsFlow": "reset credentials", - "clientAuthenticationFlow": "clients", - "dockerAuthenticationFlow": "docker auth", - "attributes": {}, - "keycloakVersion": "10.0.1", - "userManagedAccessAllowed": false -} \ No newline at end of file diff --git a/example/keycloak-cloudfront-portal/securityRealm2.json b/example/keycloak-cloudfront-portal/securityRealm2.json deleted file mode 100644 index b77e8c4..0000000 --- a/example/keycloak-cloudfront-portal/securityRealm2.json +++ /dev/null @@ -1,2329 +0,0 @@ -{ - "id": "securityRealm2", - "realm": "securityRealm2", - "notBefore": 0, - "revokeRefreshToken": false, - "refreshTokenMaxReuse": 0, - "accessTokenLifespan": 300, - "accessTokenLifespanForImplicitFlow": 900, - "ssoSessionIdleTimeout": 1800, - "ssoSessionMaxLifespan": 36000, - "ssoSessionIdleTimeoutRememberMe": 0, - "ssoSessionMaxLifespanRememberMe": 0, - "offlineSessionIdleTimeout": 2592000, - "offlineSessionMaxLifespanEnabled": false, - "offlineSessionMaxLifespan": 5184000, - "clientSessionIdleTimeout": 0, - "clientSessionMaxLifespan": 0, - "accessCodeLifespan": 60, - "accessCodeLifespanUserAction": 300, - "accessCodeLifespanLogin": 1800, - "actionTokenGeneratedByAdminLifespan": 43200, - "actionTokenGeneratedByUserLifespan": 300, - "enabled": true, - "sslRequired": "external", - "registrationAllowed": false, - "registrationEmailAsUsername": false, - "rememberMe": false, - "verifyEmail": false, - "loginWithEmailAllowed": true, - "duplicateEmailsAllowed": false, - "resetPasswordAllowed": false, - "editUsernameAllowed": false, - "bruteForceProtected": false, - "permanentLockout": false, - "maxFailureWaitSeconds": 900, - "minimumQuickLoginWaitSeconds": 60, - "waitIncrementSeconds": 60, - "quickLoginCheckMilliSeconds": 1000, - "maxDeltaTimeSeconds": 43200, - "failureFactor": 30, - "roles": { - "realm": [ - { - "name": "securityRealmRole", - "composite": false, - "clientRole": false, - "containerId": "securityRealm2", - "attributes": {} - }, - { - - "name": "offline_access", - "description": "${role_offline-access}", - "composite": false, - "clientRole": false, - "containerId": "securityRealm2", - "attributes": {} - }, - { - - "name": "uma_authorization", - "description": "${role_uma_authorization}", - "composite": false, - "clientRole": false, - "containerId": "securityRealm2", - "attributes": {} - } - ], - "client": { - "realm-management": [ - { - - "name": "query-clients", - "description": "${role_query-clients}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "query-groups", - "description": "${role_query-groups}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "realm-admin", - "description": "${role_realm-admin}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-clients", - "query-groups", - "view-events", - "query-realms", - "manage-realm", - "view-authorization", - "impersonation", - "manage-users", - "create-client", - "view-identity-providers", - "manage-identity-providers", - "manage-clients", - "query-users", - "view-users", - "manage-events", - "view-realm", - "manage-authorization", - "view-clients" - ] - } - }, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "view-events", - "description": "${role_view-events}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "query-realms", - "description": "${role_query-realms}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "manage-realm", - "description": "${role_manage-realm}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "view-authorization", - "description": "${role_view-authorization}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "impersonation", - "description": "${role_impersonation}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "manage-users", - "description": "${role_manage-users}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "create-client", - "description": "${role_create-client}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "view-identity-providers", - "description": "${role_view-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "manage-clients", - "description": "${role_manage-clients}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "manage-identity-providers", - "description": "${role_manage-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "query-users", - "description": "${role_query-users}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "view-users", - "description": "${role_view-users}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-groups", - "query-users" - ] - } - }, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "manage-events", - "description": "${role_manage-events}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "view-realm", - "description": "${role_view-realm}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "view-clients", - "description": "${role_view-clients}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-clients" - ] - } - }, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - - "name": "manage-authorization", - "description": "${role_manage-authorization}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - } - ], - "security-admin-console": [], - "securityRealmClient": [ - { - - "name": "uma_protection", - "composite": false, - "clientRole": true, - "containerId": "2df50633-618d-41d9-961d-68470cfd2dc4", - "attributes": {} - } - ], - "admin-cli": [], - "account-console": [], - "broker": [ - { - - "name": "read-token", - "description": "${role_read-token}", - "composite": false, - "clientRole": true, - "containerId": "c45259be-d524-4e9e-93a5-68af7df7acf0", - "attributes": {} - } - ], - "account": [ - { - - "name": "manage-account-links", - "description": "${role_manage-account-links}", - "composite": false, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - }, - { - - "name": "view-applications", - "description": "${role_view-applications}", - "composite": false, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - }, - { - - "name": "view-consent", - "description": "${role_view-consent}", - "composite": false, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - }, - { - - "name": "view-profile", - "description": "${role_view-profile}", - "composite": false, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - }, - { - - "name": "manage-account", - "description": "${role_manage-account}", - "composite": true, - "composites": { - "client": { - "account": [ - "manage-account-links" - ] - } - }, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - }, - { - - "name": "manage-consent", - "description": "${role_manage-consent}", - "composite": true, - "composites": { - "client": { - "account": [ - "view-consent" - ] - } - }, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - } - ] - } - }, - "groups": [], - "defaultRoles": [ - "uma_authorization", - "offline_access" - ], - "requiredCredentials": [ - "password" - ], - "otpPolicyType": "totp", - "otpPolicyAlgorithm": "HmacSHA1", - "otpPolicyInitialCounter": 0, - "otpPolicyDigits": 6, - "otpPolicyLookAheadWindow": 1, - "otpPolicyPeriod": 30, - "otpSupportedApplications": [ - "FreeOTP", - "Google Authenticator" - ], - "webAuthnPolicyRpEntityName": "keycloak", - "webAuthnPolicySignatureAlgorithms": [ - "ES256" - ], - "webAuthnPolicyRpId": "", - "webAuthnPolicyAttestationConveyancePreference": "not specified", - "webAuthnPolicyAuthenticatorAttachment": "not specified", - "webAuthnPolicyRequireResidentKey": "not specified", - "webAuthnPolicyUserVerificationRequirement": "not specified", - "webAuthnPolicyCreateTimeout": 0, - "webAuthnPolicyAvoidSameAuthenticatorRegister": false, - "webAuthnPolicyAcceptableAaguids": [], - "webAuthnPolicyPasswordlessRpEntityName": "keycloak", - "webAuthnPolicyPasswordlessSignatureAlgorithms": [ - "ES256" - ], - "webAuthnPolicyPasswordlessRpId": "", - "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified", - "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified", - "webAuthnPolicyPasswordlessRequireResidentKey": "not specified", - "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified", - "webAuthnPolicyPasswordlessCreateTimeout": 0, - "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false, - "webAuthnPolicyPasswordlessAcceptableAaguids": [], - "users": [ - { - "username": "user", - "enabled": true, - "email": "user@example.com", - "firstName": "user", - "lastName": "Example", - "realmRoles": [ - "uma_authorization", - "securityRealmRole" - ], - "clientRoles": { - "account": [ - "view-profile", - "manage-account" - ] - } - }, - { - "username": "user2", - "enabled": true, - "email": "user2@example.com", - "firstName": "user2", - "lastName": "Example", - "realmRoles": [ - "uma_authorization", - "securityRealmRole" - ], - "clientRoles": { - "account": [ - "view-profile", - "manage-account" - ] - } - }, - { - - "createdTimestamp": 1591013898421, - "username": "service-account-securityrealmclient", - "enabled": true, - "totp": false, - "emailVerified": false, - "serviceAccountClientId": "securityRealmClient", - "disableableCredentialTypes": [], - "requiredActions": [], - "realmRoles": [ - "offline_access", - "uma_authorization" - ], - "clientRoles": { - "securityRealmClient": [ - "uma_protection" - ], - "account": [ - "view-profile", - "manage-account" - ] - }, - "notBefore": 0, - "groups": [] - } - ], - "scopeMappings": [ - { - "clientScope": "offline_access", - "roles": [ - "offline_access" - ] - } - ], - "clientScopeMappings": { - "account": [ - { - "client": "account-console", - "roles": [ - "manage-account" - ] - } - ] - }, - "clients": [ - { - - "clientId": "account", - "name": "${client_account}", - "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/securityRealm2/account/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "defaultRoles": [ - "view-profile", - "manage-account" - ], - "redirectUris": [ - "/realms/securityRealm2/account/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - - "clientId": "account-console", - "name": "${client_account-console}", - "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/securityRealm2/account/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [ - "/realms/securityRealm2/account/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "pkce.code.challenge.method": "S256" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "protocolMappers": [ - { - - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": {} - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - - "clientId": "admin-cli", - "name": "${client_admin-cli}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": false, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - - "clientId": "broker", - "name": "${client_broker}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - - "clientId": "realm-management", - "name": "${client_realm-management}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": true, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ] - }, - { - - "clientId": "security-admin-console", - "name": "${client_security-admin-console}", - "rootUrl": "${authAdminUrl}", - "baseUrl": "/admin/securityRealm2/console/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [ - "/admin/securityRealm2/console/*" - ], - "webOrigins": [ - "+" - ], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "pkce.code.challenge.method": "S256" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "protocolMappers": [ - { - - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - - "clientId": "securityRealmClient", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-jwt", - "secret": "**********", - "redirectUris": [ - "*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": true, - "authorizationServicesEnabled": true, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "saml.assertion.signature": "false", - "saml.force.post.binding": "false", - "saml.multivalued.roles": "false", - "saml.encrypt": "false", - "use.jwks.url": "true", - "saml.server.signature": "false", - "saml.server.signature.keyinfo.ext": "false", - "exclude.session.state.from.auth.response": "false", - "jwks.url": "http://localhost:9000/cert", - "saml_force_name_id_format": "false", - "saml.client.signature": "false", - "tls.client.certificate.bound.access.tokens": "false", - "saml.authnstatement": "false", - "display.on.consent.screen": "false", - "saml.onetimeuse.condition": "false" - }, - "authenticationFlowBindingOverrides": { - "browser": "2fb21a60-58bc-416c-9c2e-c6caf234f4e1" - }, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, - "protocolMappers": [ - { - - "name": "Client IP Address", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientAddress", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientAddress", - "jsonType.label": "String" - } - }, - { - - "name": "Client ID", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientId", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientId", - "jsonType.label": "String" - } - }, - { - - "name": "Client Host", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientHost", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientHost", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ], - "authorizationSettings": { - "allowRemoteResourceManagement": true, - "policyEnforcementMode": "ENFORCING", - "resources": [ - { - "name": "securityRealmResource", - "ownerManagedAccess": false, - "displayName": "securityRealm Resource", - "attributes": {}, - "uris": [] - } - ], - "policies": [ - { - "name": "securityRealm Polici", - "type": "role", - "logic": "POSITIVE", - "decisionStrategy": "UNANIMOUS", - "config": { - "roles": "[{\"id\":\"securityRealmRole\",\"required\":true}]" - } - }, - { - - "name": "securityRealm Permission", - "type": "resource", - "logic": "POSITIVE", - "decisionStrategy": "UNANIMOUS", - "config": { - "resources": "[\"securityRealmResource\"]", - "applyPolicies": "[\"securityRealm Polici\"]" - } - } - ], - "scopes": [], - "decisionStrategy": "UNANIMOUS" - } - } - ], - "clientScopes": [ - { - "name": "address", - "description": "OpenID Connect built-in scope: address", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${addressScopeConsentText}" - }, - "protocolMappers": [ - { - "name": "address", - "protocol": "openid-connect", - "protocolMapper": "oidc-address-mapper", - "consentRequired": false, - "config": { - "user.attribute.formatted": "formatted", - "user.attribute.country": "country", - "user.attribute.postal_code": "postal_code", - "userinfo.token.claim": "true", - "user.attribute.street": "street", - "id.token.claim": "true", - "user.attribute.region": "region", - "access.token.claim": "true", - "user.attribute.locality": "locality" - } - } - ] - }, - { - "name": "email", - "description": "OpenID Connect built-in scope: email", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${emailScopeConsentText}" - }, - "protocolMappers": [ - { - "name": "email", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "email", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email", - "jsonType.label": "String" - } - }, - { - - "name": "email verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "emailVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email_verified", - "jsonType.label": "boolean" - } - } - ] - }, - { - "name": "microprofile-jwt", - "description": "Microprofile - JWT built-in scope", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "false" - }, - "protocolMappers": [ - { - - "name": "groups", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", - "consentRequired": false, - "config": { - "multivalued": "true", - "user.attribute": "foo", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "groups", - "jsonType.label": "String" - } - }, - { - "name": "upn", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "username", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "upn", - "jsonType.label": "String" - } - } - ] - }, - { - - "name": "offline_access", - "description": "OpenID Connect built-in scope: offline_access", - "protocol": "openid-connect", - "attributes": { - "consent.screen.text": "${offlineAccessScopeConsentText}", - "display.on.consent.screen": "true" - } - }, - { - - "name": "phone", - "description": "OpenID Connect built-in scope: phone", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${phoneScopeConsentText}" - }, - "protocolMappers": [ - { - - "name": "phone number", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "phoneNumber", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number", - "jsonType.label": "String" - } - }, - { - - "name": "phone number verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "phoneNumberVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number_verified", - "jsonType.label": "boolean" - } - } - ] - }, - { - - "name": "profile", - "description": "OpenID Connect built-in scope: profile", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${profileScopeConsentText}" - }, - "protocolMappers": [ - { - - "name": "username", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "username", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "preferred_username", - "jsonType.label": "String" - } - }, - { - - "name": "gender", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "gender", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "gender", - "jsonType.label": "String" - } - }, - { - - "name": "profile", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "profile", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "profile", - "jsonType.label": "String" - } - }, - { - - "name": "picture", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "picture", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "picture", - "jsonType.label": "String" - } - }, - { - - "name": "middle name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "middleName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "middle_name", - "jsonType.label": "String" - } - }, - { - - "name": "zoneinfo", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "zoneinfo", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "zoneinfo", - "jsonType.label": "String" - } - }, - { - - "name": "updated at", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "updatedAt", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "updated_at", - "jsonType.label": "String" - } - }, - { - - "name": "website", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "website", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "website", - "jsonType.label": "String" - } - }, - { - - "name": "nickname", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "nickname", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "nickname", - "jsonType.label": "String" - } - }, - { - - "name": "given name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "firstName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "given_name", - "jsonType.label": "String" - } - }, - { - - "name": "family name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "lastName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "family_name", - "jsonType.label": "String" - } - }, - { - - "name": "full name", - "protocol": "openid-connect", - "protocolMapper": "oidc-full-name-mapper", - "consentRequired": false, - "config": { - "id.token.claim": "true", - "access.token.claim": "true", - "userinfo.token.claim": "true" - } - }, - { - - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - }, - { - - "name": "birthdate", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "birthdate", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "birthdate", - "jsonType.label": "String" - } - } - ] - }, - { - - "name": "role_list", - "description": "SAML role list", - "protocol": "saml", - "attributes": { - "consent.screen.text": "${samlRoleListScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - - "name": "role list", - "protocol": "saml", - "protocolMapper": "saml-role-list-mapper", - "consentRequired": false, - "config": { - "single": "false", - "attribute.nameformat": "Basic", - "attribute.name": "Role" - } - } - ] - }, - { - - "name": "roles", - "description": "OpenID Connect scope for add user roles to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "true", - "consent.screen.text": "${rolesScopeConsentText}" - }, - "protocolMappers": [ - { - - "name": "realm roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", - "consentRequired": false, - "config": { - "user.attribute": "foo", - "access.token.claim": "true", - "claim.name": "realm_access.roles", - "jsonType.label": "String", - "multivalued": "true" - } - }, - { - - "name": "client roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-client-role-mapper", - "consentRequired": false, - "config": { - "user.attribute": "foo", - "access.token.claim": "true", - "claim.name": "resource_access.${client_id}.roles", - "jsonType.label": "String", - "multivalued": "true" - } - }, - { - - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": {} - } - ] - }, - { - - "name": "web-origins", - "description": "OpenID Connect scope for add allowed web origins to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "false", - "consent.screen.text": "" - }, - "protocolMappers": [ - { - - "name": "allowed web origins", - "protocol": "openid-connect", - "protocolMapper": "oidc-allowed-origins-mapper", - "consentRequired": false, - "config": {} - } - ] - } - ], - "defaultDefaultClientScopes": [ - "roles", - "email", - "web-origins", - "profile", - "role_list" - ], - "defaultOptionalClientScopes": [ - "phone", - "offline_access", - "microprofile-jwt", - "address" - ], - "browserSecurityHeaders": { - "contentSecurityPolicyReportOnly": "", - "xContentTypeOptions": "nosniff", - "xRobotsTag": "none", - "xFrameOptions": "SAMEORIGIN", - "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", - "xXSSProtection": "1; mode=block", - "strictTransportSecurity": "max-age=31536000; includeSubDomains" - }, - "smtpServer": {}, - "eventsEnabled": false, - "eventsListeners": [ - "jboss-logging" - ], - "enabledEventTypes": [], - "adminEventsEnabled": false, - "adminEventsDetailsEnabled": false, - "identityProviders": [ - { - "alias": "securityRealm2", - "internalId": "securityRealm2-Idp", - "providerId": "keycloak-oidc", - "enabled": true, - "updateProfileFirstLoginMode": "on", - "trustEmail": true, - "storeToken": true, - "addReadTokenRoleOnCreate": false, - "authenticateByDefault": false, - "linkOnly": false, - "firstBrokerLoginFlowAlias": "portal first broker login", - "config": { - "userInfoUrl": "http://127.0.0.1:8080/auth/realms/portal/protocol/openid-connect/userinfo", - "validateSignature": "true", - "clientId": "portal-ui", - "tokenUrl": "http://127.0.0.1:8080/auth/realms/portal/protocol/openid-connect/token", - "jwksUrl": "http://127.0.0.1:8080/auth/realms/portal/protocol/openid-connect/certs", - "issuer": "http://127.0.0.1:8080/auth/realms/portal", - "useJwksUrl": "true", - "authorizationUrl": "http://127.0.0.1:8080/auth/realms/portal/protocol/openid-connect/auth", - "clientAuthMethod": "client_secret_post", - "logoutUrl": "http://127.0.0.1:8080/auth/realms/portal/protocol/openid-connect/logout", - "syncMode": "IMPORT", - "clientSecret": "ece2012c-fc01-4dca-b50b-f898c9c6c811" - } - } - ], - "components": { - "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ - { - - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "oidc-usermodel-attribute-mapper", - "oidc-sha256-pairwise-sub-mapper", - "oidc-usermodel-property-mapper", - "saml-user-property-mapper", - "saml-user-attribute-mapper", - "oidc-address-mapper", - "oidc-full-name-mapper", - "saml-role-list-mapper" - ] - } - }, - { - - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - - "name": "Consent Required", - "providerId": "consent-required", - "subType": "anonymous", - "subComponents": {}, - "config": {} - }, - { - - "name": "Max Clients Limit", - "providerId": "max-clients", - "subType": "anonymous", - "subComponents": {}, - "config": { - "max-clients": [ - "200" - ] - } - }, - { - - "name": "Trusted Hosts", - "providerId": "trusted-hosts", - "subType": "anonymous", - "subComponents": {}, - "config": { - "host-sending-registration-request-must-match": [ - "true" - ], - "client-uris-must-match": [ - "true" - ] - } - }, - { - - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "oidc-sha256-pairwise-sub-mapper", - "saml-user-property-mapper", - "saml-user-attribute-mapper", - "saml-role-list-mapper", - "oidc-full-name-mapper", - "oidc-usermodel-property-mapper", - "oidc-usermodel-attribute-mapper", - "oidc-address-mapper" - ] - } - }, - { - - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - - "name": "Full Scope Disabled", - "providerId": "scope", - "subType": "anonymous", - "subComponents": {}, - "config": {} - } - ], - "org.keycloak.keys.KeyProvider": [ - { - - "name": "rsa-generated", - "providerId": "rsa-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - - "name": "hmac-generated", - "providerId": "hmac-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "HS256" - ] - } - }, - { - - "name": "aes-generated", - "providerId": "aes-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - } - ] - }, - "internationalizationEnabled": false, - "supportedLocales": [], - "authenticationFlows": [ - { - "id": "c0826cf4-6610-42e3-8c78-b33ab563ec60", - "alias": "Handle Existing Account", - "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-confirm-link", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "REQUIRED", - "priority": 20, - "flowAlias": "Handle Existing Account - Alternatives - 0", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "9fc0c79e-c609-4a81-8ad6-9f51e6839ce8", - "alias": "Handle Existing Account - Alternatives - 0", - "description": "Subflow of Handle Existing Account with alternative executions", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-email-verification", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 20, - "flowAlias": "Verify Existing Account by Re-authentication", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "7001651e-ac41-4a4b-8031-946cab0c7dcf", - "alias": "Verify Existing Account by Re-authentication", - "description": "Reauthentication of existing account", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 20, - "flowAlias": "Verify Existing Account by Re-authentication - auth-otp-form - Conditional", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "8896138d-bccb-4c8a-af02-a817187671e1", - "alias": "Verify Existing Account by Re-authentication - auth-otp-form - Conditional", - "description": "Flow to determine if the auth-otp-form authenticator should be used or not.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "8a11db23-2ddc-4613-b05e-46fa4e98c3ad", - "alias": "browser", - "description": "browser based authentication", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-cookie", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "identity-provider-redirector", - "requirement": "ALTERNATIVE", - "priority": 25, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 30, - "flowAlias": "forms", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "1884ec82-571b-40cb-bb08-316f5e2d38af", - "alias": "clients", - "description": "Base authentication for clients", - "providerId": "client-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "client-secret", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-jwt", - "requirement": "ALTERNATIVE", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-secret-jwt", - "requirement": "ALTERNATIVE", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-x509", - "requirement": "ALTERNATIVE", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "3aacc6c8-233f-4ad6-bd64-35512bcdc0fb", - "alias": "direct grant", - "description": "OpenID Connect Resource Owner Grant", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "direct-grant-validate-username", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "direct-grant-validate-password", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 30, - "flowAlias": "direct grant - direct-grant-validate-otp - Conditional", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "4c510a06-360c-4f59-8935-004e0e5a341b", - "alias": "direct grant - direct-grant-validate-otp - Conditional", - "description": "Flow to determine if the direct-grant-validate-otp authenticator should be used or not.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "direct-grant-validate-otp", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "560f3d8a-6202-438e-8a15-0b06470d8157", - "alias": "docker auth", - "description": "Used by Docker clients to authenticate against the IDP", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "docker-http-basic-authenticator", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "fa4a5f8c-0fcf-46f6-857b-594d6478badf", - "alias": "first broker login", - "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticatorConfig": "review profile config", - "authenticator": "idp-review-profile", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "REQUIRED", - "priority": 20, - "flowAlias": "first broker login - Alternatives - 0", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "2f4222f0-6483-4e49-b200-e6070e3e1ae7", - "alias": "first broker login - Alternatives - 0", - "description": "Subflow of first broker login with alternative executions", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticatorConfig": "create unique user config", - "authenticator": "idp-create-user-if-unique", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 20, - "flowAlias": "Handle Existing Account", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "e2095d6a-80bf-479f-b134-993b270ce2fe", - "alias": "forms", - "description": "Username, password, otp and other auth forms.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 20, - "flowAlias": "forms - auth-otp-form - Conditional", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "a031da47-0393-44d7-a1d4-21d9243a7613", - "alias": "forms - auth-otp-form - Conditional", - "description": "Flow to determine if the auth-otp-form authenticator should be used or not.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "06b3ca50-b22b-4b9b-9b6b-b931fa8d9445", - "alias": "http challenge", - "description": "An authentication flow based on challenge-response HTTP Authentication Schemes", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "no-cookie-redirect", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "basic-auth", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "basic-auth-otp", - "requirement": "DISABLED", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "2fb21a60-58bc-416c-9c2e-c6caf234f4e1", - "alias": "portal browser", - "description": "browser based authentication", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": false, - "authenticationExecutions": [ - { - "authenticator": "auth-cookie", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticatorConfig": "securityRealm2", - "authenticator": "identity-provider-redirector", - "requirement": "REQUIRED", - "priority": 25, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "DISABLED", - "priority": 30, - "flowAlias": "portal browser forms", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "1ce18998-1c6d-4af6-b713-1419dc0a7780", - "alias": "portal browser forms", - "description": "Username, password, otp and other auth forms.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": false, - "authenticationExecutions": [ - { - "authenticator": "auth-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 20, - "flowAlias": "portal browser forms - auth-otp-form - Conditional", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "dfc17f6b-db78-4cfb-8da6-9b5d7c07dfe4", - "alias": "portal browser forms - auth-otp-form - Conditional", - "description": "Flow to determine if the auth-otp-form authenticator should be used or not.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": false, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "alias": "portal first broker login", - "description": "", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": false, - "authenticationExecutions": [ - { - "authenticator": "idp-create-user-if-unique", - "requirement": "ALTERNATIVE", - "priority": 0, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "idp-auto-link", - "requirement": "ALTERNATIVE", - "priority": 1, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "f70c886e-a329-4ee5-b621-e77bbac5a1fc", - "alias": "registration", - "description": "registration flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-page-form", - "requirement": "REQUIRED", - "priority": 10, - "flowAlias": "registration form", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "5f92d792-b7fd-44ce-9e86-af1b8065825e", - "alias": "registration form", - "description": "registration form", - "providerId": "form-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-user-creation", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-profile-action", - "requirement": "REQUIRED", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-password-action", - "requirement": "REQUIRED", - "priority": 50, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-recaptcha-action", - "requirement": "DISABLED", - "priority": 60, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "636b68b0-a51c-4d5c-900d-2009b923389f", - "alias": "reset credentials", - "description": "Reset credentials for a user if they forgot their password or something", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "reset-credentials-choose-user", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-credential-email", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-password", - "requirement": "REQUIRED", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "CONDITIONAL", - "priority": 40, - "flowAlias": "reset credentials - reset-otp - Conditional", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "58b7f5b2-2e64-45ca-a37a-c77c62bd5763", - "alias": "reset credentials - reset-otp - Conditional", - "description": "Flow to determine if the reset-otp authenticator should be used or not.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-otp", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "a30cb687-5462-4a3d-8f96-8fe156ced242", - "alias": "saml ecp", - "description": "SAML ECP Profile Authentication Flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "http-basic-authenticator", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - } - ], - "authenticatorConfig": [ - { - "id": "7f5f2951-7060-44d7-8b72-acedcda6e5b4", - "alias": "create unique user config", - "config": { - "require.password.update.after.registration": "false" - } - }, - { - "id": "a7e617de-55aa-4717-8ec0-d5ed1b1d1131", - "alias": "review profile config", - "config": { - "update.profile.on.first.login": "missing" - } - }, - { - "id": "5e12a81e-443c-48ab-95a4-8193ff2dcf33", - "alias": "securityRealm2", - "config": { - "defaultProvider": "securityRealm2" - } - } - ], - "requiredActions": [ - { - "alias": "CONFIGURE_TOTP", - "name": "Configure OTP", - "providerId": "CONFIGURE_TOTP", - "enabled": true, - "defaultAction": false, - "priority": 10, - "config": {} - }, - { - "alias": "terms_and_conditions", - "name": "Terms and Conditions", - "providerId": "terms_and_conditions", - "enabled": false, - "defaultAction": false, - "priority": 20, - "config": {} - }, - { - "alias": "UPDATE_PASSWORD", - "name": "Update Password", - "providerId": "UPDATE_PASSWORD", - "enabled": true, - "defaultAction": false, - "priority": 30, - "config": {} - }, - { - "alias": "UPDATE_PROFILE", - "name": "Update Profile", - "providerId": "UPDATE_PROFILE", - "enabled": true, - "defaultAction": false, - "priority": 40, - "config": {} - }, - { - "alias": "VERIFY_EMAIL", - "name": "Verify Email", - "providerId": "VERIFY_EMAIL", - "enabled": true, - "defaultAction": false, - "priority": 50, - "config": {} - }, - { - "alias": "update_user_locale", - "name": "Update User Locale", - "providerId": "update_user_locale", - "enabled": true, - "defaultAction": false, - "priority": 1000, - "config": {} - } - ], - "browserFlow": "browser", - "registrationFlow": "registration", - "directGrantFlow": "direct grant", - "resetCredentialsFlow": "reset credentials", - "clientAuthenticationFlow": "clients", - "dockerAuthenticationFlow": "docker auth", - "attributes": {}, - "keycloakVersion": "10.0.1", - "userManagedAccessAllowed": false -} \ No newline at end of file diff --git a/example/keycloak-cloudfront-portal/src/components/App.js b/example/keycloak-cloudfront-portal/src/components/App.js deleted file mode 100644 index 8b43a31..0000000 --- a/example/keycloak-cloudfront-portal/src/components/App.js +++ /dev/null @@ -1,95 +0,0 @@ -import React from 'react'; -import Container from '@material-ui/core/Container'; -import { Paper } from '@material-ui/core'; -import TableContainer from '@material-ui/core/TableContainer'; -import Table from '@material-ui/core/Table'; -import { makeStyles } from '@material-ui/styles'; -import TableHead from '@material-ui/core/TableHead'; -import TableRow from '@material-ui/core/TableRow'; -import TableBody from '@material-ui/core/TableBody'; -import TableCell from '@material-ui/core/TableCell'; -import { - getTenantCookie, - getTenantCookieValue, - getTenant, - getTenants, -} from 'keycloak-lambda-cloudfront-ui'; - -const fetch = require('axios'); - -const TENANT_APIS = {}; - -async function fetchData(url, method = 'GET', headers) { - const ret = await fetch({ - url, - method, - headers, - transformResponse: (req) => req, - withCredentials: true, - }); - return ret.data; -} - -export default -class App extends React.Component { - // eslint-disable-next-line class-methods-use-this - - async componentDidMount() { - const tenants = getTenants(); - // eslint-disable-next-line no-plusplus - for (let i = 0; i < tenants.length; i++) { - const row = tenants[i]; - if (row.realm !== 'portal') { - // eslint-disable-next-line no-await-in-loop - const ret = await fetchData(`/tenants/${row.realm}/api`); - const tenant = getTenant(row.realm, row.resource); - TENANT_APIS[row.realm] = { data: ret, tenant: tenant.resourceSession }; - } else { - TENANT_APIS[row.realm] = { data: ' - ' }; - } - } - this.forceUpdate(); - } - - // eslint-disable-next-line class-methods-use-this - render() { - const classes = makeStyles({ - table: { - minWidth: 650, - }, - }); - const tenants = getTenants().filter((tenant) => tenant.realm !== 'portal'); - return ( - - - - - - Tenant Name - Client Name - Cookie Name - Access Token - Protected Api Response - Last Used - - - - {tenants.map((row) => ( - - - {row.realm} - - {row.resource} - {getTenantCookie(row.realm, row.resource)} - {getTenantCookieValue(getTenantCookie(row.realm, row.resource))} - {TENANT_APIS[row.realm] ? TENANT_APIS[row.realm].data : ' - '} - {TENANT_APIS[row.realm] ? TENANT_APIS[row.realm].tenant.status : 'Undefined'} - - ))} - -
-
-
- ); - } -} diff --git a/example/keycloak-cloudfront-portal/src/components/Header.js b/example/keycloak-cloudfront-portal/src/components/Header.js deleted file mode 100644 index 83a7f72..0000000 --- a/example/keycloak-cloudfront-portal/src/components/Header.js +++ /dev/null @@ -1,126 +0,0 @@ -import React from 'react'; -import { makeStyles } from '@material-ui/styles'; -import AppBar from '@material-ui/core/AppBar'; -import Toolbar from '@material-ui/core/Toolbar'; -import IconButton from '@material-ui/core/IconButton'; -import Menu from '@material-ui/core/Menu'; -import MenuItem from '@material-ui/core/MenuItem'; -import Typography from '@material-ui/core/Typography'; -import { AccountCircle } from '@material-ui/icons'; -import { getDecodedTenantToken, getTenants, getTenant } from 'keycloak-lambda-cloudfront-ui'; - -function useStyles() { - return makeStyles((theme) => ({ - root: { - flexGrow: 1, - }, - menuButton: { - marginRight: theme.spacing(2), - }, - title: { - flexGrow: 1, - }, - })); -} - -export default -class Header extends React.Component { - constructor(props) { - super(props); - this.state = { - anchorEl: null, token1: null, token2: null, - }; - } - - async componentDidMount() { - try { - if (getTenants().find(((tenant) => tenant.realm === 'securityRealm1'))) { - const t1 = await getDecodedTenantToken('securityRealm1', 'securityRealmClient'); - const tenant1 = getTenant('securityRealm1', 'securityRealmClient'); - this.setState({ token1: t1, tenant1: tenant1.resourceSession }); - } - if (getTenants().find(((tenant) => tenant.realm === 'securityRealm2'))) { - const t2 = await getDecodedTenantToken('securityRealm2', 'securityRealmClient'); - const tenant2 = getTenant('securityRealm2', 'securityRealmClient'); - this.setState({ token2: t2, tenant2: tenant2.resourceSession }); - } - } catch (e) { - console.error(e); - } - } - - handleMenu = (event) => { - this.setState({ anchorEl: event.currentTarget }); - }; - - handleClose = () => { - this.setState({ anchorEl: null }); - }; - - handleSwitch =(tenant) => { - window.location.replace(tenant); - }; - - handleLogout =(realm, resource) => { - window.location.replace(`/${realm}/${resource}/logout`); - }; - - render() { - // const [anchorEl, setAnchorEl] = React.useState(null); - // const open = Boolean(anchorEl); - const { - anchorEl, token1, token2, tenant1, tenant2, - } = this.state; - const open = Boolean(anchorEl); - const classes = useStyles(); - return ( -
- - - - You are Logged In. - -
- - - - - this.handleSwitch('/tenants/securityRealm1?redirectUri=/')}> - Security Realm 1 -{token1 ? `(${token1.email}${tenant1.status === 'Active' ? ' Last Used' : ''})` : ''} - - this.handleSwitch('/tenants/securityRealm2?redirectUri=/')}> - Security Realm 2 - {token2 ? `(${token2.email}${tenant2.status === 'Active' ? ' Last Used' : ''})` : ''} - - this.handleLogout('securityRealm1', 'securityRealmClient')}>Logout Security Realm 1 - this.handleLogout('securityRealm2', 'securityRealmClient')}> Logout Security Realm 2 - -
-
-
-
- ); - } -} diff --git a/example/keycloak-cloudfront-portal/src/index.js b/example/keycloak-cloudfront-portal/src/index.js deleted file mode 100644 index a247b5e..0000000 --- a/example/keycloak-cloudfront-portal/src/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import '@babel/polyfill'; -import 'typeface-roboto'; -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './components/App'; -import Header from './components/Header'; - -const Index = () => ( -
-
- -
-); - -ReactDOM.render(, - window.document.getElementById('root')); diff --git a/example/keycloak-cloudfront-portal/tenant1.html b/example/keycloak-cloudfront-portal/tenant1.html deleted file mode 100644 index a63f074..0000000 --- a/example/keycloak-cloudfront-portal/tenant1.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - CloudFront/Lambda:edge example - - -
- - diff --git a/example/keycloak-cloudfront-portal/tenant2.html b/example/keycloak-cloudfront-portal/tenant2.html deleted file mode 100644 index a63f074..0000000 --- a/example/keycloak-cloudfront-portal/tenant2.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - CloudFront/Lambda:edge example - - -
- - diff --git a/example/keycloak-cloudfront-portal/webpack.config.babel.js b/example/keycloak-cloudfront-portal/webpack.config.babel.js deleted file mode 100644 index dc9f0d8..0000000 --- a/example/keycloak-cloudfront-portal/webpack.config.babel.js +++ /dev/null @@ -1,114 +0,0 @@ -const webpack = require('webpack'); -const ProgressBarPlugin = require('progress-bar-webpack-plugin'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); -const path = require('path'); - -const env = process.env.NODE_ENV === 'production' ? 'production' : 'development'; - -const config = { - mode: env, - entry: { - main: path.join(__dirname, 'src'), - }, - target: 'web', - output: { - filename: '[name].bundle.js', - path: path.join(__dirname, 'public'), - publicPath: '/', - }, - devServer: { - contentBase: 'public', - historyApiFallback: true, - hot: false, - inline: false, - host: '0.0.0.0', - disableHostCheck: true, - port: 9000, - before(app) { - // eslint-disable-next-line global-require - const { middleware } = require('./lambdaEdgeProxy'); - - app.use('/*', middleware); - }, - }, - module: { - rules: [{ - test: /\.(js|jsx)$/, - use: ['babel-loader'], - }, - { - test: /\.scss$/, - use: [ - 'style-loader', - 'css-loader', - 'sass-loader', - ], - }, - { - test: /\.css$/, - // exclude: /node_modules/, - use: [ - 'style-loader', - 'css-loader', - ], - }, - { - test: /\.(jpe?g|png|gif|svg)$/i, - use: [ - { - loader: 'file-loader', - options: { - hash: 'sha512', - digest: 'hex', - name: 'img/[name].[ext]', - }, - }, - ], - }, - { - test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, - use: [ - { - loader: 'file-loader', - options: { - name: '[name].[ext]', - outputPath: 'fonts/', - }, - }, - ], - }, - ], - }, - plugins: [ - new ProgressBarPlugin(), - new HtmlWebpackPlugin({ - template: 'tenant1.html', - filename: 'tenant1.html', - }), - new HtmlWebpackPlugin({ - template: 'tenant2.html', - filename: 'tenant2.html', - }), - new HtmlWebpackPlugin({ - template: 'index.html', - filename: 'index.html', - }), - ], - resolve: { - alias: { - 'lambda-edge-example': path.resolve(__dirname, './lambda-edge-example'), - crypto: path.resolve(__dirname, './node_modules/crypto-js'), - }, - modules: [ - path.join(__dirname, 'src', 'app'), - path.join(__dirname), - 'node_modules', - ], - }, - stats: { - colors: true, - }, - devtool: 'source-map', -}; - -module.exports = config; diff --git a/example/keycloak-cloudfront/README.md b/example/keycloak-cloudfront/README.md deleted file mode 100644 index 4846364..0000000 --- a/example/keycloak-cloudfront/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Cloudfront(Lambda:edge) with lambda authorizer - -## 1. Start Keycloak - -### Docker -Using the image from https://hub.docker.com/r/jboss/keycloak/ -``` -docker run -p 8090:8080 -e JAVA_OPTS="-Dkeycloak.profile.feature.scripts=enabled -Dkeycloak.profile.feature.upload_scripts=enabled -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true" -e KEYCLOAK_USER=admin -e KEYCLOAK_PASSWORD=admin jboss/keycloak -``` -change JWKS URL for Tenant2: -![tenant](../../docs/tenant.png) -replace with http://:8080/cert instead of http://localhost:8080/cert -### Standard -``` -sh bin/standalone.sh -c standalone.xml -b 0.0.0.0 -Djboss.bind.address.management=0.0.0.0 --debug 8190 -Djboss.http.port=8090 -``` -### Import Realms -**Open the Keycloak admin console, click on Add Realm, click on import 'Select file', select realm-tenant1.json and realm-tenant2.json and click Create. -** -## 2. Run emulation cloudfront and lambda:edge locally - -```bash -cd lambda-edge-example -npm i -cd .. -npm i -npm run start -``` - -## 3. Deploy to cloud using aws CDK -```bash -cd keycloak-cloudfront-cdk -./deploy.sh -n "" -r "arn:aws:iam:::role/" -``` - -## 4. Users: - -| User | password | Realm Name | Client Type | -|:-------------|:----------|:--------------|:--------------------| -| tenant1 | tenant1 | tenant1 | clientId and Secret | -| tenant2 | tenant2 | Tenant2 | client jwt | - -## 5. Switch Tenant: -![vzakharchenko14-32-39](../../docs/CloudFront1.png) -![vzakharchenko14-32-39](../../docs/CloudFront2.png) - - diff --git a/example/keycloak-cloudfront/babel.config.js b/example/keycloak-cloudfront/babel.config.js deleted file mode 100644 index 007836c..0000000 --- a/example/keycloak-cloudfront/babel.config.js +++ /dev/null @@ -1,43 +0,0 @@ -module.exports = function (api) { - api.cache(true); - - const presets = [ - [ - '@babel/preset-env', - { - targets: { - esmodules: true, - }, - }, - ], - ['@babel/preset-react'], - ['@babel/preset-flow'] - ]; - - const plugins = [ - ['@babel/transform-runtime', { - helpers: false, - regenerator: true, - }], - ['@babel/plugin-proposal-decorators', { legacy: true }], - ['@babel/plugin-proposal-class-properties', { loose: true }], - '@babel/plugin-transform-object-assign', - '@babel/plugin-proposal-do-expressions', - '@babel/plugin-proposal-export-default-from', - '@babel/plugin-proposal-object-rest-spread', - '@babel/plugin-proposal-function-sent', - '@babel/plugin-proposal-optional-chaining', - '@babel/plugin-proposal-partial-application', - ]; - - if (process.env.NODE_ENV === 'test') { - plugins.push('babel-plugin-dynamic-import-node'); - } else { - plugins.push('@babel/plugin-syntax-dynamic-import'); - } - - return { - presets, - plugins, - }; -}; diff --git a/example/keycloak-cloudfront/index.html b/example/keycloak-cloudfront/index.html deleted file mode 100644 index a63f074..0000000 --- a/example/keycloak-cloudfront/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - CloudFront/Lambda:edge example - - -
- - diff --git a/example/keycloak-cloudfront/keycloak-cloudfront-cdk/cdk.json b/example/keycloak-cloudfront/keycloak-cloudfront-cdk/cdk.json deleted file mode 100644 index 8ff3dbf..0000000 --- a/example/keycloak-cloudfront/keycloak-cloudfront-cdk/cdk.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "app": "node index.js" -} \ No newline at end of file diff --git a/example/keycloak-cloudfront/keycloak-cloudfront-cdk/deploy.sh b/example/keycloak-cloudfront/keycloak-cloudfront-cdk/deploy.sh deleted file mode 100755 index 57cb270..0000000 --- a/example/keycloak-cloudfront/keycloak-cloudfront-cdk/deploy.sh +++ /dev/null @@ -1,79 +0,0 @@ -set -e - -function help -{ -echo ' -Usage deploy.sh OPTIONS - -deploy keycloak-cloudfront infrastructure - -Options: - -n, --name REQUIRED uniq id - -r, --role REQUIRED arnRole - --profile aws profile - --help Help screen -' -} - -POSITIONAL=() -while [[ $# -gt 0 ]] -do -key="$1" - -case $key in - -n|--name) - BUCKET_NAME="$2" - shift - shift - ;; - -r|--role) - ROLE="$2" - shift - shift - ;; - -profile) - PROFILE="$2" - shift - shift - ;; - --help) - help - exit - ;; - *) # unknown option - POSITIONAL+=("$1") # save it in an array for later - shift # past argument - ;; -esac -done - -set -- "${POSITIONAL[@]}" # restore positional parameters - -if [[ "x${BUCKET_NAME}" = "x" ]]; then - echo "Error: bucket name is required" - help - exit 1; -fi - -if [[ "x${ROLE}" = "x" ]]; then - echo "Error: Arn Role is required" - help - exit 1; -fi -#npm i aws-cdk -g -#npm i -#npm run build -export AWS_DEFAULT_REGION=us-east-1 -#export stackName="example-${BUCKET_NAME}" -export bucketName="${BUCKET_NAME}" -export arnRole="${ROLE}" - -if [[ "x${PROFILE}" = "x" ]]; then - cdk -v bootstrap - cdk -v deploy - exit 0; -fi - -cdk -v bootstrap --profile="${PROFILE}" -cdk -v deploy --profile="${PROFILE}" - diff --git a/example/keycloak-cloudfront/keycloak-cloudfront-cdk/index.js b/example/keycloak-cloudfront/keycloak-cloudfront-cdk/index.js deleted file mode 100644 index e2387ff..0000000 --- a/example/keycloak-cloudfront/keycloak-cloudfront-cdk/index.js +++ /dev/null @@ -1,103 +0,0 @@ -const cdk = require('@aws-cdk/core'); -const iam = require('@aws-cdk/aws-iam'); -const dynamodb = require('@aws-cdk/aws-dynamodb'); -const s3 = require('@aws-cdk/aws-s3'); -const s3Deployment = require('@aws-cdk/aws-s3-deployment'); -const lambda = require('@aws-cdk/aws-lambda'); -const cloudfront = require('@aws-cdk/aws-cloudfront'); - -const { bucketName } = process.env; -const tableName = 'exampleSessionTable'; -const roleArn = process.env.arnRole; - -class KeycloakCloudFrontExampleStack extends cdk.Stack { - constructor(parent, id, props) { - super(parent, id, props); - - const role = iam.Role.fromRoleArn(this, `Role ${bucketName}`, roleArn, { mutable: false }); - const bucket = new s3.Bucket(this, 'lambda-edge-bucket', { - accessControl: s3.BucketAccessControl.AUTHENTICATED_READ, - removalPolicy: cdk.RemovalPolicy.DESTROY, - publicReadAccess: false, - blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, - bucketName, - }); - - const lambdaEdge = new lambda.Function(this, 'lambda-edge-example', { - runtime: lambda.Runtime.NODEJS_12_X, - handler: 'index.lambda', - code: lambda.Code.fromAsset('../lambda-edge-example/dist'), - functionName: `function_${bucketName}`, - role, - memorySize: 128, - timeout: cdk.Duration.seconds(5), - }); - const VersionLambdaEdge = new lambda.Version(this, 'lambda-edge-example Version', { - lambda: lambdaEdge, - description: `lambda-edge-example Version ${Math.random() * (99999 - 1) + 1}`, - }); - - const accessIdentityId = `access-identity-${bucketName}`; - - const comment = `OriginAccessIdentity-${bucketName}`; - const oai = new cloudfront.OriginAccessIdentity(this, accessIdentityId, { - comment, - }); - - bucket.addToResourcePolicy(new iam.PolicyStatement({ - effect: iam.Effect.ALLOW, - principals: [oai.grantPrincipal], - actions: ['s3:GetObject'], - resources: [`arn:aws:s3:::${bucketName}/*`], - })); - const sessionTable = new dynamodb.Table(this, `Session ${bucketName}`, { - tableName, - partitionKey: { name: 'session', type: dynamodb.AttributeType.STRING }, - removalPolicy: cdk.RemovalPolicy.DESTROY, - timeToLiveAttribute: 'exp', - }); - sessionTable.grantFullAccess(role); - const frontWebDistribution = new cloudfront.CloudFrontWebDistribution(this, `cloudfront-${bucketName}`, { - originConfigs: [{ - s3OriginSource: { - s3BucketSource: bucket, - originAccessIdentity: oai, - }, - behaviors: [ - { - isDefaultBehavior: true, - allowedMethods: cloudfront.CloudFrontAllowedMethods.ALL, - forwardedValues: { - cookies: { forward: 'all' }, - headers: [ - 'Authorization', - 'Referer', - 'Origin', - ], - queryString: true, - }, - lambdaFunctionAssociations: [{ - lambdaFunction: VersionLambdaEdge, - eventType: cloudfront.LambdaEdgeEventType.VIEWER_REQUEST, - }], - }, - ], - }], - viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, - defaultRootObject: 'index.html', - }); - // eslint-disable-next-line no-new - new s3Deployment.BucketDeployment(this, `BucketDeployment ${bucket}`, { - destinationBucket: bucket, - role, - distribution: frontWebDistribution, - sources: [ - s3Deployment.Source.asset('../public'), - ], - }); - } -} -const app = new cdk.App(); -// eslint-disable-next-line no-new -new KeycloakCloudFrontExampleStack(app, `example-${bucketName}`); -app.synth(); diff --git a/example/keycloak-cloudfront/keycloak-cloudfront-cdk/package.json b/example/keycloak-cloudfront/keycloak-cloudfront-cdk/package.json deleted file mode 100644 index fb2abdc..0000000 --- a/example/keycloak-cloudfront/keycloak-cloudfront-cdk/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "keycloak-cloudfront-cdk", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "build": "cd ../lambda-edge-example && npm i && npm run link:dep && npm run build && cd .. && npm i && npm run build", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "vzakharchenko", - "license": "Apache-2.0", - "dependencies": { - "@aws-cdk/aws-cloudfront": "^1.101.0", - "@aws-cdk/aws-dynamodb": "^1.101.0", - "@aws-cdk/aws-lambda": "^1.101.0", - "@aws-cdk/aws-s3": "^1.101.0", - "@aws-cdk/aws-s3-deployment": "^1.101.0", - "@aws-cdk/core": "^1.101.0" - } -} diff --git a/example/keycloak-cloudfront/lambda-edge-example/babel.config.js b/example/keycloak-cloudfront/lambda-edge-example/babel.config.js deleted file mode 100644 index 5b67f34..0000000 --- a/example/keycloak-cloudfront/lambda-edge-example/babel.config.js +++ /dev/null @@ -1,33 +0,0 @@ -module.exports = function (api) { - api.cache(true); - - const presets = [ - [ - '@babel/preset-env', - { - targets: { - esmodules: true, - }, - }, - ], - ]; - const plugins = [ - ['@babel/transform-runtime', { - helpers: false, - regenerator: true, - }], - ['@babel/plugin-proposal-decorators', { decoratorsBeforeExport: true }], - ['@babel/plugin-proposal-object-rest-spread'], - ]; - - if (process.env.NODE_ENV === 'test') { - plugins.push('babel-plugin-dynamic-import-node'); - } else { - plugins.push('@babel/plugin-syntax-dynamic-import'); - } - - return { - presets, - plugins, - }; -}; diff --git a/example/keycloak-cloudfront/lambda-edge-example/index.js b/example/keycloak-cloudfront/lambda-edge-example/index.js deleted file mode 100644 index 831d2f4..0000000 --- a/example/keycloak-cloudfront/lambda-edge-example/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import { authorization } from './src/index'; - -// eslint-disable-next-line import/prefer-default-export -export const lambda = authorization; diff --git a/example/keycloak-cloudfront/lambda-edge-example/jest.config.js b/example/keycloak-cloudfront/lambda-edge-example/jest.config.js deleted file mode 100644 index 2350bb8..0000000 --- a/example/keycloak-cloudfront/lambda-edge-example/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - setupFiles: ['./unitTestConfig/jestSetup.js'], - transform: { - '^.+\\.js$': 'babel-jest', - }, - transformIgnorePatterns: ['/node_modules/'], -}; diff --git a/example/keycloak-cloudfront/lambda-edge-example/package.json b/example/keycloak-cloudfront/lambda-edge-example/package.json deleted file mode 100644 index 4f10417..0000000 --- a/example/keycloak-cloudfront/lambda-edge-example/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "lambda-edge-example", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "build": "NODE_ENV=production webpack --config webpack.config.babel.js", - "link:dep": "cd ../../.. && npm link && cd example/keycloak-cloudfront/lambda-edge-example && npm link keycloak-lambda-authorizer", - "test": "jest --maxWorkers=2" - }, - "author": "vzakharchenko", - "license": "Apache-2.0", - "devDependencies": { - "@babel/core": "^7.14.0", - "@babel/plugin-proposal-decorators": "^7.13.15", - "@babel/plugin-proposal-object-rest-spread": "^7.13.8", - "@babel/plugin-transform-runtime": "^7.13.15", - "@babel/preset-env": "^7.14.0", - "@babel/register": "^7.13.16", - "babel-jest": "^26.6.3", - "babel-loader": "^8.2.2", - "enzyme": "^3.11.0", - "jest": "^26.6.3", - "jest-date-mock": "^1.0.8", - "progress-bar-webpack-plugin": "^2.1.0", - "webpack": "^5.36.2", - "webpack-cli": "^4.6.0" - }, - "dependencies": { - "@babel/runtime": "^7.14.0", - "axios": "^0.21.1", - "cookie": "^0.4.1", - "crypto-js": "^4.0.0", - "jsonwebtoken": "^8.5.1", - "jws": "^4.0.0", - "keycloak-lambda-authorizer": "../../../", - "node-cache": "^5.1.2", - "node-forge": "^0.10.0", - "querystring": "^0.2.1", - "rsa-pem-to-jwk": "^1.1.3", - "keycloak-cloudfront-dynamodb": "^0.1.5", - "uuid": "^8.3.2" - } -} diff --git a/example/keycloak-cloudfront/lambda-edge-example/src/Tentants.js b/example/keycloak-cloudfront/lambda-edge-example/src/Tentants.js deleted file mode 100644 index f4936ee..0000000 --- a/example/keycloak-cloudfront/lambda-edge-example/src/Tentants.js +++ /dev/null @@ -1,56 +0,0 @@ -import { privateKey, publicKey } from './sessionKeys'; - -export const tenant1KeycloakJson = { - realm: 'tenant1', - 'auth-server-url': 'http://localhost:8090/auth/', - 'ssl-required': 'external', - resource: 'tenant1Client', - 'verify-token-audience': true, - credentials: { - secret: '27a2a2e2-bbe2-4949-8a24-111084a4e3ee', - }, - 'confidential-port': 0, - 'policy-enforcer': {}, -}; - -export const tenant1Options = { - enforce: { - enabled: true, - resource: { - name: 'tenant1Resource', - }, - }, -}; - -export const tenant2KeycloakJson = { - realm: 'Tenant2', - 'auth-server-url': 'http://localhost:8090/auth', - 'ssl-required': 'external', - resource: 'tenant2Client', - 'verify-token-audience': false, - credentials: { - jwt: { - 'client-key-password': 'REPLACE WITH THE KEY PASSWORD IN KEYSTORE', - 'client-keystore-file': 'REPLACE WITH THE LOCATION OF YOUR KEYSTORE FILE', - 'client-keystore-password': 'REPLACE WITH THE KEYSTORE PASSWORD', - 'client-key-alias': 'tenant2Client', - 'token-timeout': 10, - 'client-keystore-type': 'jks', - }, - }, - 'confidential-port': 0, - 'policy-enforcer': {}, -}; - -export const tenant2Options = { - keys: { - privateKey, - publicKey, - }, - enforce: { - enabled: true, - resource: { - name: 'tenant2Resource', - }, - }, -}; diff --git a/example/keycloak-cloudfront/lambda-edge-example/src/index.js b/example/keycloak-cloudfront/lambda-edge-example/src/index.js deleted file mode 100644 index cbdb5aa..0000000 --- a/example/keycloak-cloudfront/lambda-edge-example/src/index.js +++ /dev/null @@ -1,71 +0,0 @@ -import { lamdaEdge } from 'keycloak-lambda-authorizer'; -import { SessionManager } from 'keycloak-lambda-authorizer/src/edge/storage/SessionManager'; -import { LocalSessionStorage } from 'keycloak-lambda-authorizer/src/edge/storage/localSessionStorage'; -import { DynamoDbSessionStorage } from 'keycloak-cloudfront-dynamodb/DynamoDbSessionStorage'; -import { privateKey, publicKey } from './sessionKeys'; -import { - tenant1KeycloakJson, - tenant1Options, - tenant2KeycloakJson, - tenant2Options, -} from './Tentants'; - -const keycloakJson1 = tenant1KeycloakJson; -const keycloakJson2 = tenant2KeycloakJson; - -function tenant2ResponseHandler(request, options) { - const { uri } = request; - const keycloakJson = options.keycloakJson(options); - if (uri.startsWith(`/${keycloakJson.realm}/api`)) { - return { - status: '200', - statusDescription: 'OK', - body: JSON.stringify({ tenant2: 'success' }), - }; - } - return request; -} -lamdaEdge.routes.addJwksEndpoint('/cert', publicKey.key); -lamdaEdge.routes.addProtected( - ['tenant2.html', keycloakJson2.realm], - keycloakJson2, - { - ...tenant2Options, - ...{ responseHandler: tenant2ResponseHandler }, - }, -); - -function tenant1ResponseHandler(request, options) { - const { uri } = request; - const keycloakJson = options.keycloakJson(options); - if (uri.startsWith(`/${keycloakJson.realm}/api`)) { - return { - status: '200', - statusDescription: 'OK', - body: JSON.stringify({ tenant1: 'success' }), - }; - } - return request; -} - -lamdaEdge.routes.addProtected( - ['/', 'tenant1.html', keycloakJson1.realm], - keycloakJson1, - { - ...tenant1Options, - ...{ responseHandler: tenant1ResponseHandler }, - }, -); -// eslint-disable-next-line import/prefer-default-export -export async function authorization(event, context, callback) { - await lamdaEdge.lambdaEdgeRouter(event, context, new SessionManager( - event.localhost ? new LocalSessionStorage() - : new DynamoDbSessionStorage({ region: 'us-east-1' }, 'exampleSessionTable'), - { - keys: { - privateKey, - publicKey, - }, - }, - ), callback); -} diff --git a/example/keycloak-cloudfront/lambda-edge-example/src/sessionKeys.js b/example/keycloak-cloudfront/lambda-edge-example/src/sessionKeys.js deleted file mode 100644 index 5a68e3a..0000000 --- a/example/keycloak-cloudfront/lambda-edge-example/src/sessionKeys.js +++ /dev/null @@ -1,59 +0,0 @@ -const publicKey = '-----BEGIN CERTIFICATE-----\n' - + 'MIIDgzCCAmugAwIBAgIJAJTi4Mu+7fIMMA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV\n' - + 'BAYTAlVTMQ8wDQYDVQQIDAZEZW5pYWwxFDASBgNVBAcMC1NwcmluZ2ZpZWxkMQww\n' - + 'CgYDVQQKDANEaXMxFDASBgNVBAMMC2xhbWJkYS1qd2tzMB4XDTIwMDQxMjA3NDUy\n' - + 'MFoXDTIxMDQxMjA3NDUyMFowWDELMAkGA1UEBhMCVVMxDzANBgNVBAgMBkRlbmlh\n' - + 'bDEUMBIGA1UEBwwLU3ByaW5nZmllbGQxDDAKBgNVBAoMA0RpczEUMBIGA1UEAwwL\n' - + 'bGFtYmRhLWp3a3MwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqtsnm\n' - + 'VbhKd9X1rkNalJO27OmMgF9jT8olOHuyqft1xKak9B04huWWGbCj6Q03Ugp3z9ZP\n' - + 'vcowITEuaQPCRrkLCndTO8K6wSOJ1ygW8tWPkkN0okyiMVb35+0mdqHV/f1F+9PB\n' - + 'IUgFh5F9L3HXtP42pk3NbNfP//o7BAjyN2NBiN+scz2dE/wORJE1sgLi3ICXTp6K\n' - + 'XvzNlXwpWfGv4bRuTxJZ8XAjJfElihtQ6pUKDjRyYMFnx2OltFjSfTl5BiA02slF\n' - + 'TDrf7UjGc3srihCnwCl377MqhCTYK9/NZEkBkAH1yasoWjv1NSXDNAyLGLjlE1w2\n' - + 'SHQ/MwFDAZkig25HAgMBAAGjUDBOMB0GA1UdDgQWBBRD0CkykEVkbA74qJghVg9F\n' - + 'DflQgzAfBgNVHSMEGDAWgBRD0CkykEVkbA74qJghVg9FDflQgzAMBgNVHRMEBTAD\n' - + 'AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAm69bZRa104V7ftm5Sl4BYhH5BGYq+QJG2\n' - + '+vS8S56GO07ExrD+pEPW0LUeFICVf33XFrN3QFGk87MJQVDac7GxV43JB4qsOCj0\n' - + 'Sbe0Vyu+oY/wVthtdv3Z7GuwLS/OsIWRKtYxA0IvIDlQyXXmh8E9fL+ZTNKo0iSi\n' - + 'p/H5lWGBSNrMKZNkjPJ59n6EKiNChMrNsz+nk5C8efhEqopToMfJKr1swI0/jP7l\n' - + '9kmEAZePVJamyYJt+hyN89E5wFvEYuzTOXkQpHZB7achhLnepAZTeWD1814WNHaU\n' - + '/qN33+fW7+7N3qHDm1YGWrxUBnFdczEguG6l2MSHTBVMk+/rp60B\n' - + '-----END CERTIFICATE-----\n'; - -const privateKey = '-----BEGIN PRIVATE KEY-----\n' - + 'MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCqtsnmVbhKd9X1\n' - + 'rkNalJO27OmMgF9jT8olOHuyqft1xKak9B04huWWGbCj6Q03Ugp3z9ZPvcowITEu\n' - + 'aQPCRrkLCndTO8K6wSOJ1ygW8tWPkkN0okyiMVb35+0mdqHV/f1F+9PBIUgFh5F9\n' - + 'L3HXtP42pk3NbNfP//o7BAjyN2NBiN+scz2dE/wORJE1sgLi3ICXTp6KXvzNlXwp\n' - + 'WfGv4bRuTxJZ8XAjJfElihtQ6pUKDjRyYMFnx2OltFjSfTl5BiA02slFTDrf7UjG\n' - + 'c3srihCnwCl377MqhCTYK9/NZEkBkAH1yasoWjv1NSXDNAyLGLjlE1w2SHQ/MwFD\n' - + 'AZkig25HAgMBAAECggEAdU/fNrW5SxNGqOnzxw9K4u2zIKYm5qwyEZnbB0/gSXG1\n' - + 'wq0uV2X750YIKNtCBb4PC357m5iklKZ6kZYAy0SmbHvou/3ZN1T6AwMjvYFqWJr+\n' - + 'V+wgFWUqinmKcmAbnl5H6gu/3Hvubj5XMFumM8Fg4FUwKfad54XUgzGmpCyDvMge\n' - + '+jJYTQDmZaDGFKyc+LXeT/W1r53Xzq4IesZsv91CA4P7sxuSH3+2SIIeKTLBhhxd\n' - + 'wzjdZ7jZhOWnxsGcJaQWS0T9mbeRnIPT153bNBYPIaP4p5yPgUdzad/UyGiY6nO1\n' - + 'xJ48Pf6/WspK7t54zRTEJkb9gZvu8w2pMyupAMBW4QKBgQDSMOeKx1cStL9K4APV\n' - + '8j7PH//sbKBQea3pV1aC9EiYhj9kmeaIEGHKZBc6nTaJ8tCvET67jymPqJLBqyPU\n' - + 'ef87YelAgD3XV42vorTHXJX+9DU58YKpblirdjVYpcoPNlke3cRde01NGw5S6JSh\n' - + 'e9nNIjTccVqZTjLNdSrrgmKWuwKBgQDP61xMuaCypuaL/mYoLiZfgpuVjO7nAooy\n' - + 'KMM/Z0D34tfRRWbCLOdchz0iWT+0F7rTzY1uOuW3cYdKdU7IS2aBPO0p6rPgCsOY\n' - + 'WNO36a9zxPEghshm21lDZYl8t4Wp5PjnXdjepequ0KNYrfVj2rar8V83cDOWarAN\n' - + 'PJwyXSi75QKBgGP0uce3cGMG7Ylv6qMNpmzdbNlD9yEOHHRBAnUYMoXGIdN3lLfU\n' - + 'Ao06+Aj5xnvnqvH2I30SYdNdeRz8g/eBZK0arM/trHsBufFyUMIV94bdH4rEnTxx\n' - + 'q10uw8O6Y9LEJ7GUCNPj1Sj72t32mOgKe9Mflz/V8B3DoEkwlQ6WXMgNAoGAGflB\n' - + '94e87nRxGo32PxC81HOhcgZAFfW4Q9nZwkLo186rvUXZN2qaoHF4jqDtl1bbjPgB\n' - + 'sgKDje4Nw5xx8g2RSZXN3s2mGNffZVm7YR89Ps4cfT65LDg8p3G4wi6+8OFcwrJz\n' - + 'lCTP83S24y4gGJBK/6HQjkFjAGhlg9HNhXEj1I0CgYBm2UOnqZ+c6Eg4m0kNlcbW\n' - + 'PLJjiOd1ahc7lSMkep6kXG9MKqiyvfvbbIkRLIxU7s8W+TG0vNJxUrXzWg9FM3Sp\n' - + 'JEr8I4E1mzB26LwvEame9bGtV9rJJEKH1JgcL5L4Yny52vAGUoC8n4bN6vRb51M2\n' - + 'aSV+AcDJyQBwjvRjN8kfdQ==\n' - + '-----END PRIVATE KEY-----\n'; - -module.exports = { - privateKey: { - key: privateKey, - }, - publicKey: { - key: publicKey, - }, -}; diff --git a/example/keycloak-cloudfront/lambda-edge-example/webpack.config.babel.js b/example/keycloak-cloudfront/lambda-edge-example/webpack.config.babel.js deleted file mode 100644 index 70bf632..0000000 --- a/example/keycloak-cloudfront/lambda-edge-example/webpack.config.babel.js +++ /dev/null @@ -1,50 +0,0 @@ -const webpack = require('webpack'); -const ProgressBarPlugin = require('progress-bar-webpack-plugin'); - -const path = require('path'); - -const env = process.env.NODE_ENV === 'production' ? 'production' : 'development'; - -const config = { - mode: env, - context: __dirname, - entry: { - index: path.join(__dirname, 'src/index.js'), - }, - target: 'node', - node: { - __dirname: false, - }, - output: { - path: path.join(__dirname, 'dist'), - filename: 'index.js', - libraryTarget: 'commonjs-module', - library: 'authorization', - }, - module: { - rules: [{ - test: /\.(js|jsx)$/, - use: ['babel-loader'], - }, - ], - }, - plugins: [ - new webpack.DefinePlugin({ - '.': '__dirname', - }), - new webpack.optimize.ModuleConcatenationPlugin(), - new ProgressBarPlugin(), - ], - resolve: { - modules: [ - path.join(__dirname, 'src'), - 'node_modules', - ], - }, - stats: { - colors: true, - }, - devtool: false, -}; - -module.exports = config; diff --git a/example/keycloak-cloudfront/lambdaEdgeProxy.js b/example/keycloak-cloudfront/lambdaEdgeProxy.js deleted file mode 100644 index a335c66..0000000 --- a/example/keycloak-cloudfront/lambdaEdgeProxy.js +++ /dev/null @@ -1,87 +0,0 @@ -import { lambda } from 'lambda-edge-example'; - -function splitUrl(url) { - if (url.indexOf('?') <= 0) { - return { - uri: url, - querystring: '', - }; - } - const querystring = url.substr(url.indexOf('?') + 1, url.length); - return { - uri: url.substr(0, url.indexOf('?')), - querystring, - }; -} - -function transformRequest(req) { - const urlQuery = splitUrl(req.originalUrl); - const headers = {}; - Object.keys(req.headers).forEach((headerName) => { - const headerValue = req.headers[headerName]; - headers[headerName] = [{ - key: headerName, - value: headerValue, - }]; - }); - headers.referer = [ - { - key: 'Referer', - value: `http://${req.headers.host}`, - }, - ]; - return { - localhost: true, - Records: [ - { - cf: { - config: { - distributionId: 'EXAMPLE', - eventType: 'local-request', - }, - request: { - uri: urlQuery.uri, - querystring: urlQuery.querystring, - method: req.method, - clientIp: '2001:cdba::3257:9652', - headers, - }, - }, - }, - ], - }; -} - -function transformResponse(response, res, next) { - if (response.clientIp && response.method) { - next(); - } else { - const resHeader = res.status(response.status); - if (response.headers) { - Object.keys(response.headers).forEach((headerName) => { - const headers = {}; - response.headers[headerName].forEach((hn) => { - if (headers[hn.key]) { - headers[hn.key].push(hn.value); - } else { - headers[hn.key] = [hn.value]; - } - }); - Object.keys(headers).forEach((hn) => { - resHeader.set(hn, headers[hn]); - }); - }); - } - res.send(response.body); - } -} - -module.exports.middleware = async (req, res, next) => { - const cb = function callback(error, r) { - if (error) { - throw new Error(error); - } - transformResponse(r, res, next); - }; - await lambda(transformRequest(req), {}, cb); -}; diff --git a/example/keycloak-cloudfront/package.json b/example/keycloak-cloudfront/package.json deleted file mode 100644 index b294b54..0000000 --- a/example/keycloak-cloudfront/package.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "name": "keycloak-cloudfront-ui", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "build": "NODE_ENV=production webpack --bail --config webpack.config.babel.js", - "start": "webpack serve --config webpack.config.babel.js", - "lint": "eslint --quiet --ext .js lambdaEdgeProxy.js && eslint --quiet --ext .js src lambda-edge-example/index.js lambda-edge-example/src keycloak-cloudfront-cdk/index.js", - "lint:fix": "eslint --fix --quiet --ext .js lambdaEdgeProxy.js && eslint --fix --quiet --ext .js src lambda-edge-example/index.js lambda-edge-example/src keycloak-cloudfront-cdk/index.js", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "vzakharchenko", - "license": "Apache-2.0", - "devDependencies": { - "@babel/core": "^7.14.0", - "@babel/plugin-proposal-class-properties": "^7.13.0", - "@babel/plugin-proposal-decorators": "^7.13.15", - "@babel/plugin-proposal-do-expressions": "^7.14.0", - "@babel/plugin-proposal-export-default-from": "^7.12.13", - "@babel/plugin-proposal-function-sent": "^7.12.13", - "@babel/plugin-proposal-object-rest-spread": "^7.13.8", - "@babel/plugin-proposal-optional-chaining": "^7.13.12", - "@babel/plugin-proposal-partial-application": "^7.12.13", - "@babel/plugin-syntax-dynamic-import": "^7.8.3", - "@babel/plugin-transform-object-assign": "^7.12.13", - "@babel/plugin-transform-react-jsx": "^7.13.12", - "@babel/plugin-transform-runtime": "^7.13.15", - "@babel/preset-env": "^7.14.0", - "@babel/preset-flow": "^7.13.13", - "@babel/preset-react": "^7.13.13", - "@babel/register": "^7.13.16", - "@material-ui/styles": "^4.11.4", - "babel-eslint": "^10.1.0", - "babel-loader": "^8.2.2", - "babel-plugin-dynamic-import-node": "^2.3.3", - "crypto-browserify": "^3.12.0", - "css-loader": "^5.2.4", - "eslint": "^7.25.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-jsx-a11y": "^6.4.1", - "eslint-plugin-react": "^7.23.2", - "file-loader": "^6.2.0", - "html-webpack-plugin": "^5.3.1", - "lambda-edge-example": "./lambda-edge-example", - "progress-bar-webpack-plugin": "^2.1.0", - "style-loader": "^2.0.0", - "webpack": "^5.36.2", - "webpack-cli": "^4.6.0", - "webpack-dev-server": "^3.11.2" - }, - "dependencies": { - "@babel/polyfill": "^7.10.1", - "@material-ui/core": "^4.11.4", - "@material-ui/icons": "^4.11.2", - "axios": "^0.21.1", - "browserify": "^17.0.0", - "crypto": "*", - "crypto-js": "^4.0.0", - "js-cookie": "^2.2.1", - "keycloak-lambda-cloudfront-ui": "^0.1.6", - "mobx-utils": "^6.0.4", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "stream": "*", - "typeface-roboto": "1.1.13", - "yallist": "^4.0.0" - } -} diff --git a/example/keycloak-cloudfront/realm-tenant1.json b/example/keycloak-cloudfront/realm-tenant1.json deleted file mode 100644 index 4c895f0..0000000 --- a/example/keycloak-cloudfront/realm-tenant1.json +++ /dev/null @@ -1,1834 +0,0 @@ -{ - "id": "tenant1", - "realm": "tenant1", - "notBefore": 0, - "revokeRefreshToken": false, - "refreshTokenMaxReuse": 0, - "accessTokenLifespan": 300, - "accessTokenLifespanForImplicitFlow": 900, - "ssoSessionIdleTimeout": 1800, - "ssoSessionMaxLifespan": 36000, - "ssoSessionIdleTimeoutRememberMe": 0, - "ssoSessionMaxLifespanRememberMe": 0, - "offlineSessionIdleTimeout": 2592000, - "offlineSessionMaxLifespanEnabled": false, - "offlineSessionMaxLifespan": 5184000, - "accessCodeLifespan": 60, - "accessCodeLifespanUserAction": 300, - "accessCodeLifespanLogin": 1800, - "actionTokenGeneratedByAdminLifespan": 43200, - "actionTokenGeneratedByUserLifespan": 300, - "enabled": true, - "sslRequired": "external", - "registrationAllowed": false, - "registrationEmailAsUsername": false, - "rememberMe": false, - "verifyEmail": false, - "loginWithEmailAllowed": true, - "duplicateEmailsAllowed": false, - "resetPasswordAllowed": false, - "editUsernameAllowed": false, - "bruteForceProtected": false, - "permanentLockout": false, - "maxFailureWaitSeconds": 900, - "minimumQuickLoginWaitSeconds": 60, - "waitIncrementSeconds": 60, - "quickLoginCheckMilliSeconds": 1000, - "maxDeltaTimeSeconds": 43200, - "failureFactor": 30, - "users" : [ - { - "username" : "tenant1", - "enabled": true, - "email" : "tenant1@example.com", - "firstName": "tenant1", - "lastName": "Example", - "credentials" : [ - { "type" : "password", - "value" : "tenant1" } - ], - "realmRoles": [ "uma_authorization", "Tenant1 Role" ], - "clientRoles": { - "account": ["view-profile", "manage-account"] - } - } - ], - "roles": { - "realm": [ - { - "id": "ae6fc031-fbd5-4417-93ba-9358b13f9357", - "name": "Tenant1 Role", - "composite": false, - "clientRole": false, - "containerId": "tenant1", - "attributes": {} - }, - { - "id": "a90efd22-6994-47da-a70b-217ee967eda5", - "name": "uma_authorization", - "description": "${role_uma_authorization}", - "composite": false, - "clientRole": false, - "containerId": "tenant1", - "attributes": {} - }, - { - "id": "91cbca9c-bdd9-4128-923e-e6795b5b6e1a", - "name": "offline_access", - "description": "${role_offline-access}", - "composite": false, - "clientRole": false, - "containerId": "tenant1", - "attributes": {} - } - ], - "client": { - "realm-management": [ - { - "id": "f39e8fec-c83f-4e58-9b2b-4c69b37479ce", - "name": "query-clients", - "description": "${role_query-clients}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "1b350094-6751-42e6-bc62-ce65ad983c85", - "name": "view-identity-providers", - "description": "${role_view-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "72cb1a82-9db7-4cad-b65d-ea3b9befe1c7", - "name": "manage-identity-providers", - "description": "${role_manage-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "1cec986c-6878-4fbd-91ef-8776224f9610", - "name": "manage-authorization", - "description": "${role_manage-authorization}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "b4137672-7077-4077-884b-c6d8985d4159", - "name": "view-clients", - "description": "${role_view-clients}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-clients" - ] - } - }, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "9f88d7df-fe6e-48b6-b358-ad4087acfff0", - "name": "view-authorization", - "description": "${role_view-authorization}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "2d32ba3c-60be-4783-b275-27aebe13c991", - "name": "view-events", - "description": "${role_view-events}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "5abfd196-3497-44bf-989d-9a8724a75de2", - "name": "query-groups", - "description": "${role_query-groups}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "81fe6ae3-da7d-4d70-9ede-0cd65c26007f", - "name": "view-users", - "description": "${role_view-users}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-users", - "query-groups" - ] - } - }, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "cd721b56-76f8-4943-a068-97aef1968628", - "name": "create-client", - "description": "${role_create-client}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "80e788d7-d4a5-469a-a000-9a28a4a04a37", - "name": "manage-realm", - "description": "${role_manage-realm}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "a74954be-0f0b-4be1-a407-23bb6c7ed5d7", - "name": "query-users", - "description": "${role_query-users}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "43068aaa-69b7-4a22-a4e1-ce0d4a96e4a6", - "name": "realm-admin", - "description": "${role_realm-admin}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-clients", - "view-identity-providers", - "manage-identity-providers", - "manage-authorization", - "view-clients", - "view-authorization", - "view-events", - "query-groups", - "view-users", - "create-client", - "manage-realm", - "query-users", - "impersonation", - "query-realms", - "manage-users", - "manage-events", - "view-realm", - "manage-clients" - ] - } - }, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "6d800227-8e2a-47be-8bd8-c42852af3ab4", - "name": "impersonation", - "description": "${role_impersonation}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "40ba82f6-bcce-4098-98ea-a088a599696c", - "name": "query-realms", - "description": "${role_query-realms}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "64f38622-aa98-4d6c-8155-cd780b98fd7c", - "name": "manage-users", - "description": "${role_manage-users}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "5ad7abda-669a-4049-925a-edcabbba2770", - "name": "manage-events", - "description": "${role_manage-events}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "c49e1bfc-247e-450e-817f-fbdcfb114070", - "name": "view-realm", - "description": "${role_view-realm}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - }, - { - "id": "0a191561-eb94-46c5-94ce-b63909550ba1", - "name": "manage-clients", - "description": "${role_manage-clients}", - "composite": false, - "clientRole": true, - "containerId": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "attributes": {} - } - ], - "tenant1Client": [ - { - "id": "15b98cad-ce9e-4138-ac20-e101fe3f3b49", - "name": "uma_protection", - "composite": false, - "clientRole": true, - "containerId": "fc23948d-d23c-48ab-b3cd-e870b28837ba", - "attributes": {} - } - ], - "security-admin-console": [], - "admin-cli": [], - "broker": [ - { - "id": "70e19ccb-f88e-4841-a16e-2ad427bb0543", - "name": "read-token", - "description": "${role_read-token}", - "composite": false, - "clientRole": true, - "containerId": "00559976-9951-40a1-9955-beb5e61e2822", - "attributes": {} - } - ], - "account": [ - { - "id": "4a803c3b-1a93-4ab6-94b4-e78cf51c5166", - "name": "view-profile", - "description": "${role_view-profile}", - "composite": false, - "clientRole": true, - "containerId": "66ba8e76-a9ba-4047-b8c9-78a586e2f77c", - "attributes": {} - }, - { - "id": "8c77d0ca-a10b-45b4-84bf-64a17302fb21", - "name": "manage-account", - "description": "${role_manage-account}", - "composite": true, - "composites": { - "client": { - "account": [ - "manage-account-links" - ] - } - }, - "clientRole": true, - "containerId": "66ba8e76-a9ba-4047-b8c9-78a586e2f77c", - "attributes": {} - }, - { - "id": "d74255b6-da1b-4293-9580-5a221530df30", - "name": "manage-account-links", - "description": "${role_manage-account-links}", - "composite": false, - "clientRole": true, - "containerId": "66ba8e76-a9ba-4047-b8c9-78a586e2f77c", - "attributes": {} - } - ] - } - }, - "groups": [], - "defaultRoles": [ - "offline_access", - "uma_authorization" - ], - "requiredCredentials": [ - "password" - ], - "otpPolicyType": "totp", - "otpPolicyAlgorithm": "HmacSHA1", - "otpPolicyInitialCounter": 0, - "otpPolicyDigits": 6, - "otpPolicyLookAheadWindow": 1, - "otpPolicyPeriod": 30, - "otpSupportedApplications": [ - "FreeOTP", - "Google Authenticator" - ], - "scopeMappings": [ - { - "clientScope": "offline_access", - "roles": [ - "offline_access" - ] - } - ], - "clients": [ - { - "id": "fc23948d-d23c-48ab-b3cd-e870b28837ba", - "clientId": "tenant1Client", - "surrogateAuthRequired": false, - "enabled": true, - "clientAuthenticatorType": "client-secret", - "secret": "27a2a2e2-bbe2-4949-8a24-111084a4e3ee", - "redirectUris": [ - "*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": true, - "authorizationServicesEnabled": true, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "saml.assertion.signature": "false", - "saml.multivalued.roles": "false", - "saml.force.post.binding": "false", - "saml.encrypt": "false", - "saml.server.signature": "false", - "saml.server.signature.keyinfo.ext": "false", - "exclude.session.state.from.auth.response": "false", - "saml_force_name_id_format": "false", - "saml.client.signature": "false", - "tls.client.certificate.bound.access.tokens": "false", - "saml.authnstatement": "false", - "display.on.consent.screen": "false", - "saml.onetimeuse.condition": "false" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, - "protocolMappers": [ - { - "id": "75372904-d5f9-4eed-8684-a1841383779d", - "name": "Client Host", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientHost", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientHost", - "jsonType.label": "String" - } - }, - { - "id": "b33da1c0-9837-4414-844e-60354a294e18", - "name": "Client IP Address", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientAddress", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientAddress", - "jsonType.label": "String" - } - }, - { - "id": "f03b7515-139d-49a1-a01f-325a6480e155", - "name": "Client ID", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientId", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientId", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ], - "authorizationSettings": { - "allowRemoteResourceManagement": true, - "policyEnforcementMode": "ENFORCING", - "resources": [ - { - "name": "tenant1Resource", - "ownerManagedAccess": false, - "displayName": "tenant1 Resource", - "attributes": {}, - "_id": "07e8afbe-f474-41ef-aee6-de68a3e22e16", - "uris": [] - } - ], - "policies": [ - { - "id": "df941580-d474-4f26-a13c-fd014c870f9e", - "name": "tenant1Policy", - "type": "role", - "logic": "POSITIVE", - "decisionStrategy": "UNANIMOUS", - "config": { - "roles": "[{\"id\":\"Tenant1 Role\",\"required\":true}]" - } - }, - { - "id": "b2223b9c-b1ae-49f9-8483-40e3f0f08bbb", - "name": "tenant1Permission", - "type": "resource", - "logic": "POSITIVE", - "decisionStrategy": "UNANIMOUS", - "config": { - "resources": "[\"tenant1Resource\"]", - "applyPolicies": "[\"tenant1Policy\"]" - } - } - ], - "scopes": [] - } - }, - { - "id": "06e8d105-a4d2-4f04-97d7-c3a90b09fe50", - "clientId": "realm-management", - "name": "${client_realm-management}", - "surrogateAuthRequired": false, - "enabled": true, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": true, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ] - }, - { - "id": "66ba8e76-a9ba-4047-b8c9-78a586e2f77c", - "clientId": "account", - "name": "${client_account}", - "baseUrl": "/auth/realms/tenant1/account", - "surrogateAuthRequired": false, - "enabled": true, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "defaultRoles": [ - "view-profile", - "manage-account" - ], - "redirectUris": [ - "/auth/realms/tenant1/account/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ] - }, - { - "id": "00559976-9951-40a1-9955-beb5e61e2822", - "clientId": "broker", - "name": "${client_broker}", - "surrogateAuthRequired": false, - "enabled": true, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ] - }, - { - "id": "5dd90fe1-d8ed-4d8a-9466-45e203480bb2", - "clientId": "security-admin-console", - "name": "${client_security-admin-console}", - "baseUrl": "/auth/admin/tenant1/console/index.html", - "surrogateAuthRequired": false, - "enabled": true, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [ - "/auth/admin/tenant1/console/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "protocolMappers": [ - { - "id": "592825d7-e6f3-4d02-ba47-7f101a6daa74", - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ] - }, - { - "id": "3a8651d5-ffe2-4f56-9898-6c0cfe2aeadd", - "clientId": "admin-cli", - "name": "${client_admin-cli}", - "surrogateAuthRequired": false, - "enabled": true, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": false, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ] - } - ], - "clientScopes": [ - { - "id": "f7b60322-91ad-4471-a4f0-39aeeddf41a5", - "name": "offline_access", - "description": "OpenID Connect built-in scope: offline_access", - "protocol": "openid-connect", - "attributes": { - "consent.screen.text": "${offlineAccessScopeConsentText}", - "display.on.consent.screen": "true" - } - }, - { - "id": "035a797b-0977-438c-a7b9-5ddc9abe6b36", - "name": "role_list", - "description": "SAML role list", - "protocol": "saml", - "attributes": { - "consent.screen.text": "${samlRoleListScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - "id": "ae2327eb-b855-44b4-b5af-0d01dc27daa0", - "name": "role list", - "protocol": "saml", - "protocolMapper": "saml-role-list-mapper", - "consentRequired": false, - "config": { - "single": "false", - "attribute.nameformat": "Basic", - "attribute.name": "Role" - } - } - ] - }, - { - "id": "e3f7c6b3-eae2-4e0c-acc9-5527437a3fbd", - "name": "profile", - "description": "OpenID Connect built-in scope: profile", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${profileScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "63e9e55d-5480-4217-b77e-eb7ea5838656", - "name": "gender", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "gender", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "gender", - "jsonType.label": "String" - } - }, - { - "id": "eb3fc865-0ff5-4c0d-8eee-bcf8a24253f3", - "name": "zoneinfo", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "zoneinfo", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "zoneinfo", - "jsonType.label": "String" - } - }, - { - "id": "7c0c4ffc-b4f2-415d-ba0c-29d3ebb897b3", - "name": "website", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "website", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "website", - "jsonType.label": "String" - } - }, - { - "id": "8c5b9b77-6928-4060-9ed3-ee5595cfa3e3", - "name": "picture", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "picture", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "picture", - "jsonType.label": "String" - } - }, - { - "id": "2c2fa213-7fb8-4e47-ae9b-653e8265b4bd", - "name": "full name", - "protocol": "openid-connect", - "protocolMapper": "oidc-full-name-mapper", - "consentRequired": false, - "config": { - "id.token.claim": "true", - "access.token.claim": "true", - "userinfo.token.claim": "true" - } - }, - { - "id": "5d375020-d180-44ff-bc21-bb4ba23eddf6", - "name": "nickname", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "nickname", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "nickname", - "jsonType.label": "String" - } - }, - { - "id": "b473560d-fe6f-4014-89bc-f2d6dade57b6", - "name": "given name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "firstName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "given_name", - "jsonType.label": "String" - } - }, - { - "id": "3f46abc1-cb6a-465f-bdec-c0a578d8841b", - "name": "username", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "username", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "preferred_username", - "jsonType.label": "String" - } - }, - { - "id": "ad7e589c-db46-4d44-9fb3-9b01ce30f1db", - "name": "birthdate", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "birthdate", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "birthdate", - "jsonType.label": "String" - } - }, - { - "id": "de06fb24-1ce6-4872-8523-6080a409cb15", - "name": "profile", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "profile", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "profile", - "jsonType.label": "String" - } - }, - { - "id": "b4e23f11-e2a6-4b20-8079-234b215ad20f", - "name": "middle name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "middleName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "middle_name", - "jsonType.label": "String" - } - }, - { - "id": "6d4d0d36-541c-4e3a-bd28-0b20cee55b91", - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - }, - { - "id": "0c3260c6-f1f8-4bd5-9dc5-cfdad1987b61", - "name": "family name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "lastName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "family_name", - "jsonType.label": "String" - } - }, - { - "id": "6ebb6be1-499c-4536-9235-85320710c200", - "name": "updated at", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "updatedAt", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "updated_at", - "jsonType.label": "String" - } - } - ] - }, - { - "id": "c9a80b0e-a98c-4f17-8825-460dc0d6165f", - "name": "email", - "description": "OpenID Connect built-in scope: email", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${emailScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "a000253d-1641-4a32-9258-92d73c009936", - "name": "email verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "emailVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email_verified", - "jsonType.label": "boolean" - } - }, - { - "id": "fb643603-7c43-47f7-828e-fc50ace23c05", - "name": "email", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "email", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email", - "jsonType.label": "String" - } - } - ] - }, - { - "id": "34cac43b-e960-43d4-af33-99d869451239", - "name": "address", - "description": "OpenID Connect built-in scope: address", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${addressScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "56cada24-6c0a-457c-9726-72f4a5af52e8", - "name": "address", - "protocol": "openid-connect", - "protocolMapper": "oidc-address-mapper", - "consentRequired": false, - "config": { - "user.attribute.formatted": "formatted", - "user.attribute.country": "country", - "user.attribute.postal_code": "postal_code", - "userinfo.token.claim": "true", - "user.attribute.street": "street", - "id.token.claim": "true", - "user.attribute.region": "region", - "access.token.claim": "true", - "user.attribute.locality": "locality" - } - } - ] - }, - { - "id": "79089d67-cf15-4fdf-b3ce-e832f3ee7eab", - "name": "phone", - "description": "OpenID Connect built-in scope: phone", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${phoneScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "d0423fd0-f5d1-4144-9ebc-faad9c3ecf63", - "name": "phone number", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "phoneNumber", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number", - "jsonType.label": "String" - } - }, - { - "id": "7ab3261f-c69f-4e32-96dc-dae7d8d608e2", - "name": "phone number verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "phoneNumberVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number_verified", - "jsonType.label": "boolean" - } - } - ] - }, - { - "id": "c1349fc0-8a6d-4a8f-91c4-03ee58d44c3e", - "name": "roles", - "description": "OpenID Connect scope for add user roles to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "true", - "consent.screen.text": "${rolesScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "151cb2ab-dc0e-4bf9-b790-22a17b130ee1", - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": {} - }, - { - "id": "195fef11-048b-4f45-90b6-ef0f3559e471", - "name": "realm roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", - "consentRequired": false, - "config": { - "user.attribute": "foo", - "access.token.claim": "true", - "claim.name": "realm_access.roles", - "jsonType.label": "String", - "multivalued": "true" - } - }, - { - "id": "598fbb26-daf3-45ba-8e05-c606a28f3dcb", - "name": "client roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-client-role-mapper", - "consentRequired": false, - "config": { - "user.attribute": "foo", - "access.token.claim": "true", - "claim.name": "resource_access.${client_id}.roles", - "jsonType.label": "String", - "multivalued": "true" - } - } - ] - }, - { - "id": "3181fcd0-9aea-46fa-8a5f-1c6512e44443", - "name": "web-origins", - "description": "OpenID Connect scope for add allowed web origins to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "false", - "consent.screen.text": "" - }, - "protocolMappers": [ - { - "id": "046771ab-13e4-4df3-a6ab-99024bfeb850", - "name": "allowed web origins", - "protocol": "openid-connect", - "protocolMapper": "oidc-allowed-origins-mapper", - "consentRequired": false, - "config": {} - } - ] - } - ], - "defaultDefaultClientScopes": [ - "role_list", - "profile", - "email", - "roles", - "web-origins" - ], - "defaultOptionalClientScopes": [ - "offline_access", - "address", - "phone" - ], - "browserSecurityHeaders": { - "contentSecurityPolicyReportOnly": "", - "xContentTypeOptions": "nosniff", - "xRobotsTag": "none", - "xFrameOptions": "SAMEORIGIN", - "xXSSProtection": "1; mode=block", - "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", - "strictTransportSecurity": "max-age=31536000; includeSubDomains" - }, - "smtpServer": {}, - "eventsEnabled": false, - "eventsListeners": [ - "jboss-logging" - ], - "enabledEventTypes": [], - "adminEventsEnabled": false, - "adminEventsDetailsEnabled": false, - "components": { - "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ - { - "id": "84eea9e1-ebac-4a9e-80e7-3b48b4e8a227", - "name": "Trusted Hosts", - "providerId": "trusted-hosts", - "subType": "anonymous", - "subComponents": {}, - "config": { - "host-sending-registration-request-must-match": [ - "true" - ], - "client-uris-must-match": [ - "true" - ] - } - }, - { - "id": "0f3cdbb6-f0c5-4a06-8bca-c6f519729955", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "oidc-usermodel-attribute-mapper", - "oidc-sha256-pairwise-sub-mapper", - "oidc-address-mapper", - "saml-role-list-mapper", - "saml-user-property-mapper", - "saml-user-attribute-mapper", - "oidc-usermodel-property-mapper", - "oidc-full-name-mapper" - ] - } - }, - { - "id": "6ec9f02d-f182-40bb-b2ba-cff3b974413e", - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - "id": "4a922dd0-6582-44f0-a40f-ed99bd36898c", - "name": "Full Scope Disabled", - "providerId": "scope", - "subType": "anonymous", - "subComponents": {}, - "config": {} - }, - { - "id": "f4059d63-6f62-430e-bdfe-70bdb44846a1", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "oidc-usermodel-attribute-mapper", - "oidc-full-name-mapper", - "saml-user-property-mapper", - "oidc-address-mapper", - "saml-user-attribute-mapper", - "oidc-sha256-pairwise-sub-mapper", - "saml-role-list-mapper", - "oidc-usermodel-property-mapper" - ] - } - }, - { - "id": "4f3e5888-fb57-4d76-b78d-bc6c8f899be6", - "name": "Max Clients Limit", - "providerId": "max-clients", - "subType": "anonymous", - "subComponents": {}, - "config": { - "max-clients": [ - "200" - ] - } - }, - { - "id": "ade91ebb-5de7-4f31-92fe-79267e7479dd", - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - "id": "f70755fb-b08c-49dd-b206-161d46c0acd2", - "name": "Consent Required", - "providerId": "consent-required", - "subType": "anonymous", - "subComponents": {}, - "config": {} - } - ], - "org.keycloak.keys.KeyProvider": [ - { - "id": "b901bd01-43aa-4065-a168-32f17f3eae8e", - "name": "rsa-generated", - "providerId": "rsa-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - "id": "676ef6bb-d12c-41e7-adf3-86e5f396e055", - "name": "aes-generated", - "providerId": "aes-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - "id": "1a08d13c-2170-4a7f-83be-201450b676eb", - "name": "hmac-generated", - "providerId": "hmac-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "HS256" - ] - } - } - ] - }, - "internationalizationEnabled": false, - "supportedLocales": [], - "authenticationFlows": [ - { - "id": "d13a13c6-5997-471e-90e8-2ffeeb798dc2", - "alias": "Handle Existing Account", - "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-confirm-link", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "idp-email-verification", - "requirement": "ALTERNATIVE", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 30, - "flowAlias": "Verify Existing Account by Re-authentication", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "99180e95-e03c-4382-ad5b-a1ec702cec06", - "alias": "Verify Existing Account by Re-authentication", - "description": "Reauthentication of existing account", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "OPTIONAL", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "bd76b909-d18b-4e95-a662-673e0e6a26c1", - "alias": "browser", - "description": "browser based authentication", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-cookie", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "identity-provider-redirector", - "requirement": "ALTERNATIVE", - "priority": 25, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 30, - "flowAlias": "forms", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "fac5f75c-032a-48ac-a7c3-df2c7e093ed7", - "alias": "clients", - "description": "Base authentication for clients", - "providerId": "client-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "client-secret", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-jwt", - "requirement": "ALTERNATIVE", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-secret-jwt", - "requirement": "ALTERNATIVE", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-x509", - "requirement": "ALTERNATIVE", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "e85bdfd5-13dd-4e77-91b0-f754b21ddaa2", - "alias": "direct grant", - "description": "OpenID Connect Resource Owner Grant", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "direct-grant-validate-username", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "direct-grant-validate-password", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "direct-grant-validate-otp", - "requirement": "OPTIONAL", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "f0a65972-9a29-4d6e-b41b-cd96c2ad14c4", - "alias": "docker auth", - "description": "Used by Docker clients to authenticate against the IDP", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "docker-http-basic-authenticator", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "0ce4de26-4bdc-4176-bec5-7884ba5dd6b0", - "alias": "first broker login", - "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticatorConfig": "review profile config", - "authenticator": "idp-review-profile", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticatorConfig": "create unique user config", - "authenticator": "idp-create-user-if-unique", - "requirement": "ALTERNATIVE", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 30, - "flowAlias": "Handle Existing Account", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "9b78092e-b949-47d7-95c6-925fc6a00935", - "alias": "forms", - "description": "Username, password, otp and other auth forms.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "OPTIONAL", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "5bdaa6e1-d7fd-412e-abce-de546098cd7b", - "alias": "http challenge", - "description": "An authentication flow based on challenge-response HTTP Authentication Schemes", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "no-cookie-redirect", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "basic-auth", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "basic-auth-otp", - "requirement": "DISABLED", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "858f5304-675e-4ff5-9b53-8ea1b6998919", - "alias": "registration", - "description": "registration flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-page-form", - "requirement": "REQUIRED", - "priority": 10, - "flowAlias": "registration form", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "0fa30c83-a7ba-43f2-8d2b-e9a5616d143a", - "alias": "registration form", - "description": "registration form", - "providerId": "form-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-user-creation", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-profile-action", - "requirement": "REQUIRED", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-password-action", - "requirement": "REQUIRED", - "priority": 50, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-recaptcha-action", - "requirement": "DISABLED", - "priority": 60, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "e2a0fd6b-3a62-4596-8c7f-61b35fd7c17c", - "alias": "reset credentials", - "description": "Reset credentials for a user if they forgot their password or something", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "reset-credentials-choose-user", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-credential-email", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-password", - "requirement": "REQUIRED", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-otp", - "requirement": "OPTIONAL", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "7b67c019-d668-4386-8369-fc669dcf599f", - "alias": "saml ecp", - "description": "SAML ECP Profile Authentication Flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "http-basic-authenticator", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - } - ], - "authenticatorConfig": [ - { - "id": "558dd507-d82b-4bd2-a3ab-8105156084dd", - "alias": "create unique user config", - "config": { - "require.password.update.after.registration": "false" - } - }, - { - "id": "cf82cf4b-14b3-440e-913b-cb0e76425cd0", - "alias": "review profile config", - "config": { - "update.profile.on.first.login": "missing" - } - } - ], - "requiredActions": [ - { - "alias": "CONFIGURE_TOTP", - "name": "Configure OTP", - "providerId": "CONFIGURE_TOTP", - "enabled": true, - "defaultAction": false, - "priority": 10, - "config": {} - }, - { - "alias": "terms_and_conditions", - "name": "Terms and Conditions", - "providerId": "terms_and_conditions", - "enabled": false, - "defaultAction": false, - "priority": 20, - "config": {} - }, - { - "alias": "UPDATE_PASSWORD", - "name": "Update Password", - "providerId": "UPDATE_PASSWORD", - "enabled": true, - "defaultAction": false, - "priority": 30, - "config": {} - }, - { - "alias": "UPDATE_PROFILE", - "name": "Update Profile", - "providerId": "UPDATE_PROFILE", - "enabled": true, - "defaultAction": false, - "priority": 40, - "config": {} - }, - { - "alias": "VERIFY_EMAIL", - "name": "Verify Email", - "providerId": "VERIFY_EMAIL", - "enabled": true, - "defaultAction": false, - "priority": 50, - "config": {} - } - ], - "browserFlow": "browser", - "registrationFlow": "registration", - "directGrantFlow": "direct grant", - "resetCredentialsFlow": "reset credentials", - "clientAuthenticationFlow": "clients", - "dockerAuthenticationFlow": "docker auth", - "attributes": { - "_browser_header.xXSSProtection": "1; mode=block", - "_browser_header.xFrameOptions": "SAMEORIGIN", - "_browser_header.strictTransportSecurity": "max-age=31536000; includeSubDomains", - "permanentLockout": "false", - "quickLoginCheckMilliSeconds": "1000", - "_browser_header.xRobotsTag": "none", - "maxFailureWaitSeconds": "900", - "minimumQuickLoginWaitSeconds": "60", - "failureFactor": "30", - "actionTokenGeneratedByUserLifespan": "300", - "maxDeltaTimeSeconds": "43200", - "_browser_header.xContentTypeOptions": "nosniff", - "offlineSessionMaxLifespan": "5184000", - "actionTokenGeneratedByAdminLifespan": "43200", - "_browser_header.contentSecurityPolicyReportOnly": "", - "bruteForceProtected": "false", - "_browser_header.contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", - "waitIncrementSeconds": "60", - "offlineSessionMaxLifespanEnabled": "false" - }, - "keycloakVersion": "4.7.0.Final", - "userManagedAccessAllowed": false -} \ No newline at end of file diff --git a/example/keycloak-cloudfront/realm-tenant2.json b/example/keycloak-cloudfront/realm-tenant2.json deleted file mode 100644 index c9641ec..0000000 --- a/example/keycloak-cloudfront/realm-tenant2.json +++ /dev/null @@ -1,1851 +0,0 @@ -{ - "id": "Tenant2", - "realm": "Tenant2", - "notBefore": 0, - "revokeRefreshToken": false, - "refreshTokenMaxReuse": 0, - "accessTokenLifespan": 300, - "accessTokenLifespanForImplicitFlow": 900, - "ssoSessionIdleTimeout": 1800, - "ssoSessionMaxLifespan": 36000, - "ssoSessionIdleTimeoutRememberMe": 0, - "ssoSessionMaxLifespanRememberMe": 0, - "offlineSessionIdleTimeout": 2592000, - "offlineSessionMaxLifespanEnabled": false, - "offlineSessionMaxLifespan": 5184000, - "accessCodeLifespan": 60, - "accessCodeLifespanUserAction": 300, - "accessCodeLifespanLogin": 1800, - "actionTokenGeneratedByAdminLifespan": 43200, - "actionTokenGeneratedByUserLifespan": 300, - "enabled": true, - "sslRequired": "external", - "registrationAllowed": false, - "registrationEmailAsUsername": false, - "rememberMe": false, - "verifyEmail": false, - "loginWithEmailAllowed": true, - "duplicateEmailsAllowed": false, - "resetPasswordAllowed": false, - "editUsernameAllowed": false, - "bruteForceProtected": false, - "permanentLockout": false, - "maxFailureWaitSeconds": 900, - "minimumQuickLoginWaitSeconds": 60, - "waitIncrementSeconds": 60, - "quickLoginCheckMilliSeconds": 1000, - "maxDeltaTimeSeconds": 43200, - "failureFactor": 30, - "users" : [ - { - "username" : "tenant1", - "enabled": true, - "email" : "tenant1@example.com", - "firstName": "tenant1", - "lastName": "Example", - "credentials" : [ - { "type" : "password", - "value" : "tenant1" } - ], - "realmRoles": [ "uma_authorization", "Tenant2Role" ], - "clientRoles": { - "account": ["view-profile", "manage-account"] - } - }, - { - "username" : "tenant2", - "enabled": true, - "email" : "tenant2@example.com", - "firstName": "tenant2", - "lastName": "Example", - "credentials" : [ - { "type" : "password", - "value" : "tenant2" } - ], - "realmRoles": [ "uma_authorization", "Tenant2Role" ], - "clientRoles": { - "account": ["view-profile", "manage-account"] - } - } - ], - "roles": { - "realm": [ - { - "id": "60351ddb-7117-4c5b-8b32-d1003e06aff5", - "name": "Tenant2Role", - "composite": false, - "clientRole": false, - "containerId": "Tenant2", - "attributes": {} - }, - { - "id": "f09709af-bc64-4732-b222-c6843ff212d7", - "name": "offline_access", - "description": "${role_offline-access}", - "composite": false, - "clientRole": false, - "containerId": "Tenant2", - "attributes": {} - }, - { - "id": "77164ff0-98fa-4e6f-a2f0-1fcf508eed48", - "name": "uma_authorization", - "description": "${role_uma_authorization}", - "composite": false, - "clientRole": false, - "containerId": "Tenant2", - "attributes": {} - } - ], - "client": { - "realm-management": [ - { - "id": "85794c03-ea8c-4fed-88db-c630f5146104", - "name": "query-clients", - "description": "${role_query-clients}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "9622c7e8-8dd6-46ad-ba49-621d0fa2950d", - "name": "query-groups", - "description": "${role_query-groups}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "7cabee9b-80f8-4064-8bbd-b157c28108c0", - "name": "realm-admin", - "description": "${role_realm-admin}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-clients", - "query-groups", - "view-events", - "query-realms", - "manage-realm", - "view-authorization", - "impersonation", - "manage-users", - "create-client", - "view-identity-providers", - "manage-clients", - "manage-identity-providers", - "query-users", - "view-users", - "manage-events", - "view-realm", - "view-clients", - "manage-authorization" - ] - } - }, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "f482e506-5ce4-4d82-b9fa-ee0513524a26", - "name": "view-events", - "description": "${role_view-events}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "88bb8a7b-8bda-420e-bf47-b900bb03b8fd", - "name": "query-realms", - "description": "${role_query-realms}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "4ee0813c-a3bd-4ee7-8940-dced1396d1fe", - "name": "manage-realm", - "description": "${role_manage-realm}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "22fedf21-9c5f-416a-9128-04fd94463e6f", - "name": "view-authorization", - "description": "${role_view-authorization}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "eea27447-b55d-43be-bc3a-65f303e63f30", - "name": "impersonation", - "description": "${role_impersonation}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "039e89eb-579d-4cbc-b12d-4b3e1be6b51b", - "name": "manage-users", - "description": "${role_manage-users}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "7d8cff8e-010e-44b9-ab6b-c38f0510af81", - "name": "create-client", - "description": "${role_create-client}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "b1379c0e-73d5-4b0e-a3af-6048e6631b65", - "name": "view-identity-providers", - "description": "${role_view-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "f34f4e16-7d47-472e-8957-a57f9b7f3363", - "name": "manage-clients", - "description": "${role_manage-clients}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "c5065dab-78b4-458a-8797-7292fe009a89", - "name": "manage-identity-providers", - "description": "${role_manage-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "175a0aa9-d0ae-4015-b72a-b2ea89027469", - "name": "query-users", - "description": "${role_query-users}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "ddcd0f87-2eed-4960-a58e-3f40817972cf", - "name": "view-users", - "description": "${role_view-users}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-groups", - "query-users" - ] - } - }, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "4e3eff90-9411-475a-9a27-2d9b6351560d", - "name": "manage-events", - "description": "${role_manage-events}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "1d696b71-6a9c-485f-bca1-7120eff35832", - "name": "view-realm", - "description": "${role_view-realm}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "855fe95d-b599-412e-bdc7-e325ed00fd1e", - "name": "view-clients", - "description": "${role_view-clients}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-clients" - ] - } - }, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - }, - { - "id": "4fffaa8d-d38f-4757-852d-97a03b923cce", - "name": "manage-authorization", - "description": "${role_manage-authorization}", - "composite": false, - "clientRole": true, - "containerId": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "attributes": {} - } - ], - "security-admin-console": [], - "admin-cli": [], - "broker": [ - { - "id": "0605c6a9-0d06-421f-a167-6de9684ac79e", - "name": "read-token", - "description": "${role_read-token}", - "composite": false, - "clientRole": true, - "containerId": "c45259be-d524-4e9e-93a5-68af7df7acf0", - "attributes": {} - } - ], - "tenant2Client": [ - { - "id": "dd9d08e7-7eba-4869-a3f2-3b305d031aa6", - "name": "uma_protection", - "composite": false, - "clientRole": true, - "containerId": "2df50633-618d-41d9-961d-68470cfd2dc4", - "attributes": {} - } - ], - "account": [ - { - "id": "11b2b854-c749-4b58-941e-3206e1840e90", - "name": "manage-account-links", - "description": "${role_manage-account-links}", - "composite": false, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - }, - { - "id": "3b8d07f4-b258-42c2-973c-323128470919", - "name": "view-profile", - "description": "${role_view-profile}", - "composite": false, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - }, - { - "id": "e4eaaa9c-5721-47de-a09a-4b915a7046c4", - "name": "manage-account", - "description": "${role_manage-account}", - "composite": true, - "composites": { - "client": { - "account": [ - "manage-account-links" - ] - } - }, - "clientRole": true, - "containerId": "851c241b-bc84-46f2-931e-17bbaad76723", - "attributes": {} - } - ] - } - }, - "groups": [], - "defaultRoles": [ - "offline_access", - "uma_authorization" - ], - "requiredCredentials": [ - "password" - ], - "otpPolicyType": "totp", - "otpPolicyAlgorithm": "HmacSHA1", - "otpPolicyInitialCounter": 0, - "otpPolicyDigits": 6, - "otpPolicyLookAheadWindow": 1, - "otpPolicyPeriod": 30, - "otpSupportedApplications": [ - "FreeOTP", - "Google Authenticator" - ], - "scopeMappings": [ - { - "clientScope": "offline_access", - "roles": [ - "offline_access" - ] - } - ], - "clients": [ - { - "id": "2df50633-618d-41d9-961d-68470cfd2dc4", - "clientId": "tenant2Client", - "surrogateAuthRequired": false, - "enabled": true, - "clientAuthenticatorType": "client-jwt", - "secret": "**********", - "redirectUris": [ - "*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": true, - "authorizationServicesEnabled": true, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "saml.assertion.signature": "false", - "saml.multivalued.roles": "false", - "saml.force.post.binding": "false", - "saml.encrypt": "false", - "use.jwks.url": "true", - "saml.server.signature": "false", - "saml.server.signature.keyinfo.ext": "false", - "exclude.session.state.from.auth.response": "false", - "jwks.url": "http://localhost:8080/cert", - "saml_force_name_id_format": "false", - "saml.client.signature": "false", - "tls.client.certificate.bound.access.tokens": "false", - "saml.authnstatement": "false", - "display.on.consent.screen": "false", - "saml.onetimeuse.condition": "false" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, - "protocolMappers": [ - { - "id": "b6084759-113c-41df-ba7d-74b945916c0c", - "name": "Client IP Address", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientAddress", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientAddress", - "jsonType.label": "String" - } - }, - { - "id": "128c8046-a6ee-42dc-b6b7-238ce3c22436", - "name": "Client ID", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientId", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientId", - "jsonType.label": "String" - } - }, - { - "id": "31df8789-2770-4bdf-b225-9b62fb0251e3", - "name": "Client Host", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientHost", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientHost", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ], - "authorizationSettings": { - "allowRemoteResourceManagement": true, - "policyEnforcementMode": "ENFORCING", - "resources": [ - { - "name": "tenant2Resource", - "ownerManagedAccess": false, - "displayName": "tenant2 Resource", - "attributes": {}, - "_id": "89492f45-3ea9-460e-861a-c6ff976f02ae", - "uris": [] - } - ], - "policies": [ - { - "id": "74d23928-8ca9-4295-891e-b2efd203df82", - "name": "tenant2 Polici", - "type": "role", - "logic": "POSITIVE", - "decisionStrategy": "UNANIMOUS", - "config": { - "roles": "[{\"id\":\"Tenant2Role\",\"required\":true}]" - } - }, - { - "id": "469a35f0-f47d-42fd-917e-9cb3785cd7fe", - "name": "tenant2 Permission", - "type": "resource", - "logic": "POSITIVE", - "decisionStrategy": "UNANIMOUS", - "config": { - "resources": "[\"tenant2Resource\"]", - "applyPolicies": "[\"tenant2 Polici\"]" - } - } - ], - "scopes": [] - } - }, - { - "id": "d78ea593-c613-4ddb-b4e1-2aa96dd3d32a", - "clientId": "realm-management", - "name": "${client_realm-management}", - "surrogateAuthRequired": false, - "enabled": true, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": true, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ] - }, - { - "id": "851c241b-bc84-46f2-931e-17bbaad76723", - "clientId": "account", - "name": "${client_account}", - "baseUrl": "/auth/realms/Tenant2/account", - "surrogateAuthRequired": false, - "enabled": true, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "defaultRoles": [ - "view-profile", - "manage-account" - ], - "redirectUris": [ - "/auth/realms/Tenant2/account/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ] - }, - { - "id": "c45259be-d524-4e9e-93a5-68af7df7acf0", - "clientId": "broker", - "name": "${client_broker}", - "surrogateAuthRequired": false, - "enabled": true, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ] - }, - { - "id": "ab8927c1-2ee8-400b-a782-2eb6938453a1", - "clientId": "security-admin-console", - "name": "${client_security-admin-console}", - "baseUrl": "/auth/admin/Tenant2/console/index.html", - "surrogateAuthRequired": false, - "enabled": true, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [ - "/auth/admin/Tenant2/console/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "protocolMappers": [ - { - "id": "5c311dde-df9e-4303-a47c-15e86718e848", - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ] - }, - { - "id": "13de1e52-f45f-4ad7-adc4-3254b97c01ea", - "clientId": "admin-cli", - "name": "${client_admin-cli}", - "surrogateAuthRequired": false, - "enabled": true, - "clientAuthenticatorType": "client-secret", - "secret": "**********", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": false, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": {}, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "role_list", - "profile", - "roles", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access" - ] - } - ], - "clientScopes": [ - { - "id": "64bf602d-c155-462e-8825-0c71face8a09", - "name": "offline_access", - "description": "OpenID Connect built-in scope: offline_access", - "protocol": "openid-connect", - "attributes": { - "consent.screen.text": "${offlineAccessScopeConsentText}", - "display.on.consent.screen": "true" - } - }, - { - "id": "f9d732e3-17f0-4698-b232-7caf74928003", - "name": "role_list", - "description": "SAML role list", - "protocol": "saml", - "attributes": { - "consent.screen.text": "${samlRoleListScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - "id": "b05d635b-0a6b-4806-925e-5fb113a2ede6", - "name": "role list", - "protocol": "saml", - "protocolMapper": "saml-role-list-mapper", - "consentRequired": false, - "config": { - "single": "false", - "attribute.nameformat": "Basic", - "attribute.name": "Role" - } - } - ] - }, - { - "id": "a221728c-ec12-41e4-955b-fcd1f12bc007", - "name": "profile", - "description": "OpenID Connect built-in scope: profile", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${profileScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "2571c29b-0b4f-45fb-aa04-160e1e45963b", - "name": "username", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "username", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "preferred_username", - "jsonType.label": "String" - } - }, - { - "id": "954d7153-1951-4c5f-9595-9142caa05455", - "name": "gender", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "gender", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "gender", - "jsonType.label": "String" - } - }, - { - "id": "28e49bf9-4cea-4f84-8c2e-9737a81c74bd", - "name": "profile", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "profile", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "profile", - "jsonType.label": "String" - } - }, - { - "id": "c05480b7-e73e-4388-ad4a-f94de06403d0", - "name": "picture", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "picture", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "picture", - "jsonType.label": "String" - } - }, - { - "id": "b2ca75fc-0b48-4328-b1a0-8ec1b88f04b8", - "name": "middle name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "middleName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "middle_name", - "jsonType.label": "String" - } - }, - { - "id": "8bacb362-58b4-4992-a2b6-82d25cc4dadf", - "name": "zoneinfo", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "zoneinfo", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "zoneinfo", - "jsonType.label": "String" - } - }, - { - "id": "1c76b19f-48cd-4ac7-aa3b-90e6a8417b1f", - "name": "updated at", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "updatedAt", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "updated_at", - "jsonType.label": "String" - } - }, - { - "id": "e57a2b3d-d511-4906-bfb2-92b29f88e35e", - "name": "website", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "website", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "website", - "jsonType.label": "String" - } - }, - { - "id": "f5d9af54-79b0-4089-b9d7-6704ad29312e", - "name": "nickname", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "nickname", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "nickname", - "jsonType.label": "String" - } - }, - { - "id": "790e7caf-316c-40f9-980d-953c227e475a", - "name": "given name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "firstName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "given_name", - "jsonType.label": "String" - } - }, - { - "id": "dba9a26c-6fcc-4ecb-af55-41238f04dd6f", - "name": "family name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "lastName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "family_name", - "jsonType.label": "String" - } - }, - { - "id": "c5369974-e227-4b60-a0c4-dd4f6970f77b", - "name": "full name", - "protocol": "openid-connect", - "protocolMapper": "oidc-full-name-mapper", - "consentRequired": false, - "config": { - "id.token.claim": "true", - "access.token.claim": "true", - "userinfo.token.claim": "true" - } - }, - { - "id": "54aab60e-7667-46da-8c84-1a4cb9448b3e", - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - }, - { - "id": "3261e540-f946-413d-b465-ea3ed6c3abe0", - "name": "birthdate", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "birthdate", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "birthdate", - "jsonType.label": "String" - } - } - ] - }, - { - "id": "82c2fa9b-cf51-4b3c-b405-0d41e85a703e", - "name": "email", - "description": "OpenID Connect built-in scope: email", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${emailScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "3866f647-8937-4e53-b2e1-f576ed78d8df", - "name": "email", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "email", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email", - "jsonType.label": "String" - } - }, - { - "id": "c7e67e47-b14f-4867-9c6a-9217919fa0db", - "name": "email verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "emailVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email_verified", - "jsonType.label": "boolean" - } - } - ] - }, - { - "id": "b396a183-abfb-4765-8a57-3530ee6c087b", - "name": "address", - "description": "OpenID Connect built-in scope: address", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${addressScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "18b6f63d-4560-4496-8e2e-b5cd163444cd", - "name": "address", - "protocol": "openid-connect", - "protocolMapper": "oidc-address-mapper", - "consentRequired": false, - "config": { - "user.attribute.formatted": "formatted", - "user.attribute.country": "country", - "user.attribute.postal_code": "postal_code", - "userinfo.token.claim": "true", - "user.attribute.street": "street", - "id.token.claim": "true", - "user.attribute.region": "region", - "access.token.claim": "true", - "user.attribute.locality": "locality" - } - } - ] - }, - { - "id": "154da9f1-6970-4d7e-b2b3-734538e8cda7", - "name": "phone", - "description": "OpenID Connect built-in scope: phone", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "consent.screen.text": "${phoneScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "a3386db2-0eb4-446a-9f4e-d9a744c3eebc", - "name": "phone number", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "phoneNumber", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number", - "jsonType.label": "String" - } - }, - { - "id": "185e64ac-3f54-4a6b-ac10-a15381d355e9", - "name": "phone number verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "userinfo.token.claim": "true", - "user.attribute": "phoneNumberVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number_verified", - "jsonType.label": "boolean" - } - } - ] - }, - { - "id": "7480ed5c-ca72-431a-8a6d-e7b3a4b5bd01", - "name": "roles", - "description": "OpenID Connect scope for add user roles to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "true", - "consent.screen.text": "${rolesScopeConsentText}" - }, - "protocolMappers": [ - { - "id": "4913b271-4793-4732-a46e-2cef99e46415", - "name": "realm roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", - "consentRequired": false, - "config": { - "user.attribute": "foo", - "access.token.claim": "true", - "claim.name": "realm_access.roles", - "jsonType.label": "String", - "multivalued": "true" - } - }, - { - "id": "9d8800a2-c616-4e6e-8326-7fdbe031c099", - "name": "client roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-client-role-mapper", - "consentRequired": false, - "config": { - "user.attribute": "foo", - "access.token.claim": "true", - "claim.name": "resource_access.${client_id}.roles", - "jsonType.label": "String", - "multivalued": "true" - } - }, - { - "id": "df1cb601-2a63-41ed-92cb-4c44bed12ec2", - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": {} - } - ] - }, - { - "id": "8b2cc18a-1414-47e4-9770-6ad553eec6d1", - "name": "web-origins", - "description": "OpenID Connect scope for add allowed web origins to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "false", - "consent.screen.text": "" - }, - "protocolMappers": [ - { - "id": "973f3eb5-0b24-4a08-b0de-d8a2169d0d37", - "name": "allowed web origins", - "protocol": "openid-connect", - "protocolMapper": "oidc-allowed-origins-mapper", - "consentRequired": false, - "config": {} - } - ] - } - ], - "defaultDefaultClientScopes": [ - "role_list", - "profile", - "email", - "roles", - "web-origins" - ], - "defaultOptionalClientScopes": [ - "offline_access", - "address", - "phone" - ], - "browserSecurityHeaders": { - "contentSecurityPolicyReportOnly": "", - "xContentTypeOptions": "nosniff", - "xRobotsTag": "none", - "xFrameOptions": "SAMEORIGIN", - "xXSSProtection": "1; mode=block", - "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", - "strictTransportSecurity": "max-age=31536000; includeSubDomains" - }, - "smtpServer": {}, - "eventsEnabled": false, - "eventsListeners": [ - "jboss-logging" - ], - "enabledEventTypes": [], - "adminEventsEnabled": false, - "adminEventsDetailsEnabled": false, - "components": { - "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ - { - "id": "1be3f2d9-3f69-4ef3-9376-d54be250953e", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "saml-user-attribute-mapper", - "oidc-address-mapper", - "oidc-sha256-pairwise-sub-mapper", - "saml-role-list-mapper", - "oidc-usermodel-attribute-mapper", - "saml-user-property-mapper", - "oidc-usermodel-property-mapper", - "oidc-full-name-mapper" - ] - } - }, - { - "id": "33bf846f-624b-47d4-b819-ddf0cdb857c2", - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - "id": "692a7e65-f13f-43b5-9875-3056babe7a27", - "name": "Consent Required", - "providerId": "consent-required", - "subType": "anonymous", - "subComponents": {}, - "config": {} - }, - { - "id": "5788e6ef-772e-4484-8fba-91155e39727a", - "name": "Max Clients Limit", - "providerId": "max-clients", - "subType": "anonymous", - "subComponents": {}, - "config": { - "max-clients": [ - "200" - ] - } - }, - { - "id": "099f6d01-5bac-4e52-8baf-51b943e58fbd", - "name": "Trusted Hosts", - "providerId": "trusted-hosts", - "subType": "anonymous", - "subComponents": {}, - "config": { - "host-sending-registration-request-must-match": [ - "true" - ], - "client-uris-must-match": [ - "true" - ] - } - }, - { - "id": "269c4bca-f48d-44af-9790-c857aad8b546", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "saml-user-property-mapper", - "oidc-address-mapper", - "saml-role-list-mapper", - "oidc-full-name-mapper", - "oidc-usermodel-property-mapper", - "saml-user-attribute-mapper", - "oidc-usermodel-attribute-mapper", - "oidc-sha256-pairwise-sub-mapper" - ] - } - }, - { - "id": "106ccd06-10e3-4a31-b080-2a05cc0be26d", - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - "id": "99c652a8-968e-4601-887a-84b26de6c00e", - "name": "Full Scope Disabled", - "providerId": "scope", - "subType": "anonymous", - "subComponents": {}, - "config": {} - } - ], - "org.keycloak.keys.KeyProvider": [ - { - "id": "0a9c31e4-2a58-48ce-abd8-e77ad78794cc", - "name": "rsa-generated", - "providerId": "rsa-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - "id": "185ac1e3-dffd-4ac7-8266-1e17d74a21be", - "name": "hmac-generated", - "providerId": "hmac-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "HS256" - ] - } - }, - { - "id": "9ba292cb-5293-4366-be46-cf9f75019c83", - "name": "aes-generated", - "providerId": "aes-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - } - ] - }, - "internationalizationEnabled": false, - "supportedLocales": [], - "authenticationFlows": [ - { - "id": "52183d25-64f1-48cf-98aa-9e703adb9411", - "alias": "Handle Existing Account", - "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-confirm-link", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "idp-email-verification", - "requirement": "ALTERNATIVE", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 30, - "flowAlias": "Verify Existing Account by Re-authentication", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "6b2d4b3b-94a7-4c70-bca7-a3448892f4e6", - "alias": "Verify Existing Account by Re-authentication", - "description": "Reauthentication of existing account", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "OPTIONAL", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "8d0cda12-cb6b-4fde-b32d-9a0eb786ad2e", - "alias": "browser", - "description": "browser based authentication", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-cookie", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "identity-provider-redirector", - "requirement": "ALTERNATIVE", - "priority": 25, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 30, - "flowAlias": "forms", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "80ab31e3-8ba8-4a69-9351-3371c0309f9b", - "alias": "clients", - "description": "Base authentication for clients", - "providerId": "client-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "client-secret", - "requirement": "ALTERNATIVE", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-jwt", - "requirement": "ALTERNATIVE", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-secret-jwt", - "requirement": "ALTERNATIVE", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "client-x509", - "requirement": "ALTERNATIVE", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "123450a5-7e5b-4b3f-b6ef-77f9231eb58b", - "alias": "direct grant", - "description": "OpenID Connect Resource Owner Grant", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "direct-grant-validate-username", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "direct-grant-validate-password", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "direct-grant-validate-otp", - "requirement": "OPTIONAL", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "e35f7b3c-00a2-402b-bd93-0e7febb1a008", - "alias": "docker auth", - "description": "Used by Docker clients to authenticate against the IDP", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "docker-http-basic-authenticator", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "b1608446-2a8d-4270-82e7-ca2219ad9eee", - "alias": "first broker login", - "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticatorConfig": "review profile config", - "authenticator": "idp-review-profile", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticatorConfig": "create unique user config", - "authenticator": "idp-create-user-if-unique", - "requirement": "ALTERNATIVE", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "requirement": "ALTERNATIVE", - "priority": 30, - "flowAlias": "Handle Existing Account", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "604ed278-d2be-449d-9cb2-84aa6cff9a45", - "alias": "forms", - "description": "Username, password, otp and other auth forms.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-username-password-form", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-otp-form", - "requirement": "OPTIONAL", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "f4519861-7179-4507-b8be-fdd604c5d17a", - "alias": "http challenge", - "description": "An authentication flow based on challenge-response HTTP Authentication Schemes", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "no-cookie-redirect", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "basic-auth", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "basic-auth-otp", - "requirement": "DISABLED", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "auth-spnego", - "requirement": "DISABLED", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "ddeeb6b8-8c87-4153-9672-582bf4c0d93f", - "alias": "registration", - "description": "registration flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-page-form", - "requirement": "REQUIRED", - "priority": 10, - "flowAlias": "registration form", - "userSetupAllowed": false, - "autheticatorFlow": true - } - ] - }, - { - "id": "0097984c-c582-43e4-a0eb-ed7dfb51965e", - "alias": "registration form", - "description": "registration form", - "providerId": "form-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-user-creation", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-profile-action", - "requirement": "REQUIRED", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-password-action", - "requirement": "REQUIRED", - "priority": 50, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "registration-recaptcha-action", - "requirement": "DISABLED", - "priority": 60, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "3f282d81-27d5-4551-a25b-ddbeaac9fa2b", - "alias": "reset credentials", - "description": "Reset credentials for a user if they forgot their password or something", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "reset-credentials-choose-user", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-credential-email", - "requirement": "REQUIRED", - "priority": 20, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-password", - "requirement": "REQUIRED", - "priority": 30, - "userSetupAllowed": false, - "autheticatorFlow": false - }, - { - "authenticator": "reset-otp", - "requirement": "OPTIONAL", - "priority": 40, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - }, - { - "id": "cd598d1b-2c9d-4966-814a-8a244291bba0", - "alias": "saml ecp", - "description": "SAML ECP Profile Authentication Flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "http-basic-authenticator", - "requirement": "REQUIRED", - "priority": 10, - "userSetupAllowed": false, - "autheticatorFlow": false - } - ] - } - ], - "authenticatorConfig": [ - { - "id": "813c6277-c329-46b2-93d6-61505296275a", - "alias": "create unique user config", - "config": { - "require.password.update.after.registration": "false" - } - }, - { - "id": "aa227446-36b6-4f15-84f8-e758f166e16e", - "alias": "review profile config", - "config": { - "update.profile.on.first.login": "missing" - } - } - ], - "requiredActions": [ - { - "alias": "CONFIGURE_TOTP", - "name": "Configure OTP", - "providerId": "CONFIGURE_TOTP", - "enabled": true, - "defaultAction": false, - "priority": 10, - "config": {} - }, - { - "alias": "terms_and_conditions", - "name": "Terms and Conditions", - "providerId": "terms_and_conditions", - "enabled": false, - "defaultAction": false, - "priority": 20, - "config": {} - }, - { - "alias": "UPDATE_PASSWORD", - "name": "Update Password", - "providerId": "UPDATE_PASSWORD", - "enabled": true, - "defaultAction": false, - "priority": 30, - "config": {} - }, - { - "alias": "UPDATE_PROFILE", - "name": "Update Profile", - "providerId": "UPDATE_PROFILE", - "enabled": true, - "defaultAction": false, - "priority": 40, - "config": {} - }, - { - "alias": "VERIFY_EMAIL", - "name": "Verify Email", - "providerId": "VERIFY_EMAIL", - "enabled": true, - "defaultAction": false, - "priority": 50, - "config": {} - } - ], - "browserFlow": "browser", - "registrationFlow": "registration", - "directGrantFlow": "direct grant", - "resetCredentialsFlow": "reset credentials", - "clientAuthenticationFlow": "clients", - "dockerAuthenticationFlow": "docker auth", - "attributes": { - "_browser_header.xXSSProtection": "1; mode=block", - "_browser_header.xFrameOptions": "SAMEORIGIN", - "_browser_header.strictTransportSecurity": "max-age=31536000; includeSubDomains", - "permanentLockout": "false", - "quickLoginCheckMilliSeconds": "1000", - "_browser_header.xRobotsTag": "none", - "maxFailureWaitSeconds": "900", - "minimumQuickLoginWaitSeconds": "60", - "failureFactor": "30", - "actionTokenGeneratedByUserLifespan": "300", - "maxDeltaTimeSeconds": "43200", - "_browser_header.xContentTypeOptions": "nosniff", - "offlineSessionMaxLifespan": "5184000", - "actionTokenGeneratedByAdminLifespan": "43200", - "_browser_header.contentSecurityPolicyReportOnly": "", - "bruteForceProtected": "false", - "_browser_header.contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", - "waitIncrementSeconds": "60", - "offlineSessionMaxLifespanEnabled": "false" - }, - "keycloakVersion": "4.7.0.Final", - "userManagedAccessAllowed": false -} diff --git a/example/keycloak-cloudfront/src/components/App.js b/example/keycloak-cloudfront/src/components/App.js deleted file mode 100644 index 421030b..0000000 --- a/example/keycloak-cloudfront/src/components/App.js +++ /dev/null @@ -1,87 +0,0 @@ -import React from 'react'; -import Container from '@material-ui/core/Container'; -import { Paper } from '@material-ui/core'; -import TableContainer from '@material-ui/core/TableContainer'; -import Table from '@material-ui/core/Table'; -import { makeStyles } from '@material-ui/styles'; -import TableHead from '@material-ui/core/TableHead'; -import TableRow from '@material-ui/core/TableRow'; -import TableBody from '@material-ui/core/TableBody'; -import TableCell from '@material-ui/core/TableCell'; -import { - getTenantCookie, - getTenantCookieValue, - getTenants, -} from 'keycloak-lambda-cloudfront-ui'; - -const fetch = require('axios'); - -const TENANT_APIS = {}; - -async function fetchData(url, method = 'GET', headers) { - const ret = await fetch({ - url, - method, - headers, - transformResponse: (req) => req, - withCredentials: true, - }); - return ret.data; -} - -export default -class App extends React.Component { - // eslint-disable-next-line class-methods-use-this - - async componentDidMount() { - const tenants = getTenants(); - // eslint-disable-next-line no-plusplus - for (let i = 0; i < tenants.length; i++) { - const row = tenants[i]; - // eslint-disable-next-line no-await-in-loop - const ret = await fetchData(`/${row.realm}/api`); - TENANT_APIS[row.realm] = ret; - } - this.forceUpdate(); - } - - // eslint-disable-next-line class-methods-use-this - render() { - const classes = makeStyles({ - table: { - minWidth: 650, - }, - }); - const tenants = getTenants(); - return ( - - - - - - Tenant Name - Client Name - Cookie Name - Access Token - Protected Api Response - - - - {tenants.map((row) => ( - - - {row.realm} - - {row.resource} - {getTenantCookie(row.realm, row.resource)} - {getTenantCookieValue(getTenantCookie(row.realm, row.resource))} - {TENANT_APIS[row.realm]} - - ))} - -
-
-
- ); - } -} diff --git a/example/keycloak-cloudfront/src/components/Header.js b/example/keycloak-cloudfront/src/components/Header.js deleted file mode 100644 index 418fbec..0000000 --- a/example/keycloak-cloudfront/src/components/Header.js +++ /dev/null @@ -1,122 +0,0 @@ -import React from 'react'; -import { makeStyles } from '@material-ui/styles'; -import AppBar from '@material-ui/core/AppBar'; -import Toolbar from '@material-ui/core/Toolbar'; -import IconButton from '@material-ui/core/IconButton'; -import Menu from '@material-ui/core/Menu'; -import MenuItem from '@material-ui/core/MenuItem'; -import Typography from '@material-ui/core/Typography'; -import { AccountCircle } from '@material-ui/icons'; -import { getDecodedTenantToken, getTenants } from 'keycloak-lambda-cloudfront-ui'; - -function useStyles() { - return makeStyles((theme) => ({ - root: { - flexGrow: 1, - }, - menuButton: { - marginRight: theme.spacing(2), - }, - title: { - flexGrow: 1, - }, - })); -} - -export default -class Header extends React.Component { - constructor(props) { - super(props); - this.state = { - anchorEl: null, token1: null, token2: null, - }; - } - - async componentDidMount() { - try { - if (getTenants('tenant1', 'tenant1Client')) { - const t1 = await getDecodedTenantToken('tenant1', 'tenant1Client'); - this.setState({ token1: t1 }); - } - if (getTenants('Tenant2', 'tenant2Client')) { - const t2 = await getDecodedTenantToken('Tenant2', 'tenant2Client'); - this.setState({ token2: t2 }); - } - } catch (e) { - console.error(e); - } - } - - handleMenu = (event) => { - this.setState({ anchorEl: event.currentTarget }); - }; - - handleClose = () => { - this.setState({ anchorEl: null }); - }; - - handleSwitch =(tenant) => { - window.location.replace(tenant); - }; - - handleLogout =(realm, resource) => { - window.location.replace(`/${realm}/${resource}/logout`); - }; - - render() { - // const [anchorEl, setAnchorEl] = React.useState(null); - // const open = Boolean(anchorEl); - const { anchorEl, token1, token2 } = this.state; - const open = Boolean(anchorEl); - const classes = useStyles(); - return ( -
- - - - You are Logged In. - -
- - - - - this.handleSwitch('/tenant1.html')}> -Tenant 1 -{token1 ? token1.email : ''} - - this.handleSwitch('/tenant2.html')}> -Tenant 2 -{token2 ? token2.email : ''} - - this.handleLogout('tenant1', 'tenant1Client')}>Logout Tenant1 - this.handleLogout('Tenant2', 'tenant2Client')}> Logout Tenant2 - -
-
-
-
- ); - } -} diff --git a/example/keycloak-cloudfront/src/index.js b/example/keycloak-cloudfront/src/index.js deleted file mode 100644 index a247b5e..0000000 --- a/example/keycloak-cloudfront/src/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import '@babel/polyfill'; -import 'typeface-roboto'; -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './components/App'; -import Header from './components/Header'; - -const Index = () => ( -
-
- -
-); - -ReactDOM.render(, - window.document.getElementById('root')); diff --git a/example/keycloak-cloudfront/tenant1.html b/example/keycloak-cloudfront/tenant1.html deleted file mode 100644 index a63f074..0000000 --- a/example/keycloak-cloudfront/tenant1.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - CloudFront/Lambda:edge example - - -
- - diff --git a/example/keycloak-cloudfront/tenant2.html b/example/keycloak-cloudfront/tenant2.html deleted file mode 100644 index a63f074..0000000 --- a/example/keycloak-cloudfront/tenant2.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - CloudFront/Lambda:edge example - - -
- - diff --git a/example/keycloak-cloudfront/webpack.config.babel.js b/example/keycloak-cloudfront/webpack.config.babel.js deleted file mode 100644 index 8cc3982..0000000 --- a/example/keycloak-cloudfront/webpack.config.babel.js +++ /dev/null @@ -1,113 +0,0 @@ -const webpack = require('webpack'); -const ProgressBarPlugin = require('progress-bar-webpack-plugin'); -const HtmlWebpackPlugin = require('html-webpack-plugin'); -const path = require('path'); - -const env = process.env.NODE_ENV === 'production' ? 'production' : 'development'; - -const config = { - mode: env, - entry: { - main: path.join(__dirname, 'src'), - }, - target: 'web', - output: { - filename: '[name].bundle.js', - path: path.join(__dirname, 'public'), - publicPath: '/', - }, - devServer: { - contentBase: 'public', - historyApiFallback: true, - hot: false, - inline: false, - host: '0.0.0.0', - disableHostCheck: true, - before(app) { - // eslint-disable-next-line global-require - const { middleware } = require('./lambdaEdgeProxy'); - - app.use('/*', middleware); - }, - }, - module: { - rules: [{ - test: /\.(js|jsx)$/, - use: ['babel-loader'], - }, - { - test: /\.scss$/, - use: [ - 'style-loader', - 'css-loader', - 'sass-loader', - ], - }, - { - test: /\.css$/, - // exclude: /node_modules/, - use: [ - 'style-loader', - 'css-loader', - ], - }, - { - test: /\.(jpe?g|png|gif|svg)$/i, - use: [ - { - loader: 'file-loader', - options: { - hash: 'sha512', - digest: 'hex', - name: 'img/[name].[ext]', - }, - }, - ], - }, - { - test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, - use: [ - { - loader: 'file-loader', - options: { - name: '[name].[ext]', - outputPath: 'fonts/', - }, - }, - ], - }, - ], - }, - plugins: [ - new ProgressBarPlugin(), - new HtmlWebpackPlugin({ - template: 'tenant1.html', - filename: 'tenant1.html', - }), - new HtmlWebpackPlugin({ - template: 'tenant2.html', - filename: 'tenant2.html', - }), - new HtmlWebpackPlugin({ - template: 'index.html', - filename: 'index.html', - }), - ], - resolve: { - alias: { - 'lambda-edge-example': path.resolve(__dirname, './lambda-edge-example'), - crypto: path.resolve(__dirname, './node_modules/crypto-js'), - }, - modules: [ - path.join(__dirname, 'src', 'app'), - path.join(__dirname), - 'node_modules', - ], - }, - stats: { - colors: true, - }, - devtool: 'source-map', -}; - -module.exports = config; diff --git a/keycloak-cloudfront-dynamodb/.npmignore b/keycloak-cloudfront-dynamodb/.npmignore deleted file mode 100644 index b9ce9d4..0000000 --- a/keycloak-cloudfront-dynamodb/.npmignore +++ /dev/null @@ -1,16 +0,0 @@ -.*.swp -._* -.DS_Store -.git -.hg -.npmrc -.lock-wscript -.svn -.wafpickle-* -config.gypi -CVS -npm-debug.log -example/* -.circleci/* -.idea/* -package-lock.json \ No newline at end of file diff --git a/keycloak-cloudfront-dynamodb/DynamoDbSessionStorage.js b/keycloak-cloudfront-dynamodb/DynamoDbSessionStorage.js deleted file mode 100644 index bc8d233..0000000 --- a/keycloak-cloudfront-dynamodb/DynamoDbSessionStorage.js +++ /dev/null @@ -1,102 +0,0 @@ -const AWS = require('aws-sdk'); - -function saveSession(dbSettings) { - return async (sessionId, - exp, - tenant, - externalToken) => { - const item = { - TableName: dbSettings.tableName, - Item: { - session: { - S: sessionId, - }, - exp: { - N: String(exp), - }, - }, - }; - item.Item[tenant] = { S: JSON.stringify(externalToken) }; - await dbSettings.dynamodb.putItem(item).promise(); - }; -} - -function updateSession(dbSettings) { - return async (sessionId, tenant, externalToken) => { - await dbSettings.dynamodb.updateItem({ - TableName: dbSettings.tableName, - Key: { - session: { S: sessionId }, - }, - UpdateExpression: `SET ${tenant} = :e`, - ExpressionAttributeValues: { - ':e': { S: `${JSON.stringify(externalToken)}` }, - }, - }).promise(); - }; -} - -function transformResponse(item, tenant) { - const itemData = { - session: item.session.S, - email: item.email.S, - }; - - if (item[tenant]) { - itemData[tenant] = JSON.parse(item[tenant].S); - } - return itemData; -} - -function getSessionIfExists(dbSettings) { - return async (session) => { - try { - const data = await dbSettings.dynamodb.getItem({ - TableName: dbSettings.tableName, - Key: { - session: { S: session }, - }, - }).promise(); - console.debug(`session: ${JSON.stringify(data)}`); - const item = data.Item; - return !item - || ( - Object.keys(item).length === 0 - && item.constructor === Object) ? null : transformResponse(item); - } catch (e) { - console.log(e); - return null; - } - }; -} - -async function deleteSession(dbSettings) { - return async (session) => { - try { - await dbSettings.dynamodb.deleteItem({ - TableName: dbSettings.tableName, - Key: { - session: { S: session }, - }, - }).promise(); - } catch (e) { - console.log(e); - } - }; -} - -function DynamoDbSessionStorage(awsConfig, tableName) { - AWS.config.update(awsConfig); - const dynamodb = new AWS.DynamoDB({ apiVersion: '2012-08-10' }); - const dbSettings = { dynamodb, tableName }; - return { - saveSession: saveSession(dbSettings), - updateSession: updateSession(dbSettings), - getSessionIfExists: getSessionIfExists(dbSettings), - deleteSession: deleteSession(dbSettings), - }; -} - -module.exports = { - DynamoDbSessionStorage, -}; diff --git a/keycloak-cloudfront-dynamodb/package.json b/keycloak-cloudfront-dynamodb/package.json deleted file mode 100644 index 2569c82..0000000 --- a/keycloak-cloudfront-dynamodb/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "keycloak-cloudfront-dynamodb", - "version": "0.1.5", - "description": "dynamodb module for keycloak-lambda-authorizer", - "main": "DynamoDbSessionStorage.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/vzakharchenko/keycloak-lambda-authorizer.git" - }, - "keywords": [ - "keycloak-lambda-authorizer", - "dynamodb" - ], - "author": "vzakharchenko", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/vzakharchenko/keycloak-lambda-authorizer/issues" - }, - "homepage": "https://github.com/vzakharchenko/keycloak-lambda-authorizer#readme", - "dependencies": { - "aws-sdk": "^2.896.0" - } -} diff --git a/src/edge/lambdaEdgeUtils.js b/src/edge/lambdaEdgeUtils.js deleted file mode 100644 index 2260294..0000000 --- a/src/edge/lambdaEdgeUtils.js +++ /dev/null @@ -1,80 +0,0 @@ -const jwt = require('jsonwebtoken'); -const { clientJWT } = require('../clientAuthorization'); - -const { getUrl } = require('../utils/restCalls'); - -function getHostHeader(request) { - return request.headers && request.headers.referer ? request.headers.referer[0].value : ''; -} - -function isLocalhost(request) { - const hostHeaderValue = getHostHeader(request); - return !hostHeaderValue || hostHeaderValue.startsWith('http://localhost'); -} - -function getHostUrl(request) { - return getUrl(getHostHeader(request)); -} - -function updateResponse(request, response) { - if (response.headers && response.headers['set-cookie']) { - response.headers['set-cookie'].forEach((hn) => { - // eslint-disable-next-line no-param-reassign - hn.value = `${hn.value}${isLocalhost(request) ? '' : `; Domain=${getHostHeader(request)}; Secure`}`; - }); - } -} - -function tenantName(keycloakJson) { - return `${keycloakJson.realm}-${keycloakJson.resource}`; -} - -async function validateState(state, options) { - if (!state) { - return null; - } - const stateJWT = jwt.decode(state, { complete: true }); - if (!stateJWT || !stateJWT.header) { - throw new Error('invalid token (header part)'); - } else { - const { alg } = stateJWT.header; - if (alg.toLowerCase() !== 'none' && !alg.toLowerCase().startsWith('hs')) { - try { - // const hostHeader = getHostHeader(request); - // if (hostHeader && hostHeader !== sessionJWT.payload.sub) { - // throw new Error(errorWithoutRefresh('invalid token')); - // } - // Verify and decode the token - const decoded = jwt.verify(state, options.sessionManager.sessionOptions.keys.publicKey.key); - return decoded.n === tenantName(options.keycloakJson) ? decoded : null; - } catch (error) { - // Token is not valid - options.logger.error(`invalid token ${error}`); - return null; - } - } else { - throw new Error('invalid token'); - } - } -} - -async function signState(state, options) { - const timeLocal = new Date().getTime(); - const timeSec = Math.floor(timeLocal / 1000); - const payload = { - s: state, - n: tenantName(options.keycloakJson), - exp: timeSec + 600, - }; - const jwtToken = await clientJWT(payload, options.sessionManager.sessionOptions); - return jwtToken; -} - -module.exports = { - updateResponse, - getHostUrl, - tenantName, - isLocalhost, - validateState, - signState, -}; diff --git a/src/edge/lamdaEdge.js b/src/edge/lamdaEdge.js deleted file mode 100644 index 95689a1..0000000 --- a/src/edge/lamdaEdge.js +++ /dev/null @@ -1,35 +0,0 @@ -const { getRoute } = require('./router'); - -const { updateResponse } = require('./lambdaEdgeUtils'); -const routes = require('./routes/routes'); -const { lambdaEdgeOptions } = require('../utils/optionsUtils'); - -async function lambdaEdgeRouter(event, context, sessionManager, callback) { - const records = event.Records; - const options = lambdaEdgeOptions(sessionManager); - if (records && records[0] && records[0].cf) { - const { request, config } = records[0].cf; - const route = await getRoute(request, options); - if (route) { - try { - await route.handle(request, config, (error, response) => { - updateResponse(request, response); - callback(error, response); - }, options); - } catch (e) { - console.error(e); - options.route.internalServerError(request, callback); - } - } else { - callback(null, request); - } - } else { - options.route.internalServerError({}, callback); - } -} - -module.exports = { - routes, - lambdaEdgeRouter, - -}; diff --git a/src/edge/router.js b/src/edge/router.js deleted file mode 100644 index d264e5f..0000000 --- a/src/edge/router.js +++ /dev/null @@ -1,25 +0,0 @@ -const yallist = require('yallist'); - -const routes = yallist.create([]); - -async function getRoute(request, options) { - const array = routes.toArray(); - // eslint-disable-next-line no-plusplus - for (let i = 0; i < array.length; i++) { - // eslint-disable-next-line no-await-in-loop - const ret = await array[i].isRoute(request, options); - if (ret) { - return array[i]; - } - } - return null; -} - -function registerRoute(route) { - routes.push(route); -} - -module.exports = { - getRoute, - registerRoute, -}; diff --git a/src/edge/routes/Callback.js b/src/edge/routes/Callback.js deleted file mode 100644 index 0a6adcc..0000000 --- a/src/edge/routes/Callback.js +++ /dev/null @@ -1,160 +0,0 @@ -const qs = require('querystring'); -const cookie = require('cookie'); -const { getHostUrl, tenantName, validateState } = require('../lambdaEdgeUtils'); -const { getTokenByCode, exchangeRPT } = require('../../clientAuthorization'); -const { decodeAccessToken } = require('../../utils/TokenUtils'); -const { getCookie } = require('../../utils/cookiesUtils'); - -const errors = { - invalid_request: 'Invalid Request', - unauthorized_client: 'Unauthorized Client', - access_denied: 'Access Denied', - unsupported_response_type: 'Unsupported Response Type', - invalid_scope: 'Invalid Scope', - server_error: 'Server Error', - temporarily_unavailable: 'Temporarily Unavailable', -}; - -async function callbackHandler(request, options, callback) { - const { sessionManager } = options; - const host = getHostUrl(request); - const queryDict = qs.parse(request.querystring); - - options.logger.debug('Callback received'); - if (queryDict.error) { - let error = ''; - let errorDescription = ''; - let errorUri = ''; - - if (errors[queryDict.error] != null) { - // Replace with corresponding value - error = errors[queryDict.error]; - } else { - // Replace with passed in value - error = queryDict.error; - } - - if (queryDict.error_description != null) { - errorDescription = queryDict.error_description; - } else { - errorDescription = ''; - } - - if (queryDict.error_uri != null) { - errorUri = queryDict.error_uri; - } else { - errorUri = ''; - } - - options.route.unauthorized( - error, errorDescription, errorUri, request, callback, - ); - return; - } - if (!queryDict.code) { - options.route.unauthorized( - 'No Code Found', '', '', request, callback, - ); - return; - } - - let response; - try { - const keycloakJson = options.keycloakJson(options); - const decodedState = await validateState(queryDict.state, options); - if (!decodedState) { - options.logger.error('State validation failed'); - options.route.internalServerError(request, callback); - return; - } - const { code } = queryDict; - let state = decodedState.s || '/'; - - let tokenJson = await getTokenByCode(code, host, options); - let accessToken = decodeAccessToken(tokenJson); - if (options.enforce.enabled && !options.enforce.role) { - tokenJson = await exchangeRPT(accessToken.accessToken, - options.enforce.clientId || keycloakJson.resource, options); - accessToken = decodeAccessToken(tokenJson); - } - const { accessTokenDecode } = accessToken; - const sessionTimeOut = 5 * 60 * 60; - - const cookieName = tenantName(keycloakJson); - const cookies = getCookie(request, cookieName); - let sessionJWT; - if (cookies && cookies.session && await sessionManager.checkSession(cookies.session, request)) { - const decodeSession = decodeAccessToken(cookies.session).accessTokenDecode; - if (!decodeSession.tenants || !decodeSession.tenants[keycloakJson.realm] - || !decodeSession.tenants[keycloakJson.realm][keycloakJson.resource]) { - sessionJWT = await sessionManager.updateSessionToken(cookies.session, - accessTokenDecode, options); - await sessionManager.updateSession(cookies.session, - cookieName, tokenJson, options); - } else if (decodeSession.tenants[keycloakJson.realm][keycloakJson.resource] - .session_state !== accessTokenDecode.session_state) { - state = `/${keycloakJson.realm}/${keycloakJson.resource}/logout`; - sessionJWT = cookies.session; - } else { - sessionJWT = await sessionManager.updateSessionToken(cookies.session, - accessTokenDecode, options); - await sessionManager.updateSession(cookies.session, - cookieName, tokenJson, options); - } - } else { - sessionJWT = await sessionManager.createSession(host, sessionTimeOut, tokenJson, options); - } - const sessionJWTDecode = decodeAccessToken(sessionJWT).accessTokenDecode; - const refreshToken = decodeAccessToken(tokenJson.refresh_token).accessTokenDecode; - response = { - status: '302', - statusDescription: 'Found', - body: 'ID token retrieved.', - headers: { - location: [ - { - key: 'Location', - value: state, - }, - ], - 'set-cookie': [ - { - key: 'Set-Cookie', - value: cookie.serialize('KEYCLOAK_AWS_SESSION', sessionJWT, { - path: '/', - expires: new Date(sessionJWTDecode.exp * 1000), - }), - }, - { - key: 'Set-Cookie', - value: cookie.serialize(`KEYCLOAK_AWS_${cookieName}`, accessToken.accessToken, { - path: '/', - expires: new Date((accessTokenDecode.exp - 30) * 1000), - }), - }, - { - key: 'Set-Cookie', - value: cookie.serialize(`KEYCLOAK_AWS_${cookieName}_EXPIRE`, cookieName, { - path: '/', - expires: new Date((refreshToken.exp) * 1000), - }), - }, - ], - }, - }; - } catch (e) { - options.logger.error(`Internal server error: ${e}`, e); - options.route.internalServerError(request, callback); - return; - } - if (response) { - callback(null, response); - } else { - options.logger.error('Response is empty'); - options.route.internalServerError(request, callback); - } -} - -module.exports = { - callbackHandler, -}; diff --git a/src/edge/routes/Logout.js b/src/edge/routes/Logout.js deleted file mode 100644 index 5ee82ff..0000000 --- a/src/edge/routes/Logout.js +++ /dev/null @@ -1,60 +0,0 @@ -const cookie = require('cookie'); -const qs = require('querystring'); -const { getCookie } = require('../../utils/cookiesUtils'); -const { decodeAccessToken } = require('../../utils/TokenUtils'); - -const { tenantName, getHostUrl } = require('../lambdaEdgeUtils'); - -const { getKeycloakUrl } = require('../../utils/restCalls'); - -async function tenantLogout(request, options) { - const queryDict = qs.parse(request.querystring); - const keycloakJson = options.keycloakJson(options); - const tn = tenantName(keycloakJson); - const { sessionManager } = options; - const cookies = getCookie(request, tn); - let session = cookies ? cookies.session : null; - if (session && await sessionManager.checkSession(session, request)) { - session = await sessionManager.deleteTenantSession(cookies.session, options).session; - } - const sessionJWTDecode = session ? decodeAccessToken(session).accessTokenDecode : { exp: 0 }; - return { - status: '302', - statusDescription: 'Found', - body: 'Redirect to logout page', - headers: { - location: [ - { - key: 'Location', - value: `${getKeycloakUrl(keycloakJson)}/realms/${keycloakJson.realm}/protocol/openid-connect/logout?redirect_uri=${queryDict.url || `${getHostUrl(request)}/`}`, - }, - ], - 'set-cookie': [ - { - key: 'Set-Cookie', - value: cookie.serialize('KEYCLOAK_AWS_SESSION', session, { - path: '/', - expires: new Date(sessionJWTDecode.exp * 1000), - }), - }, - { - key: 'Set-Cookie', - value: cookie.serialize(`KEYCLOAK_AWS_${tn}`, '', { - path: '/', - expires: new Date(2671200000), - }), - }, { - key: 'Set-Cookie', - value: cookie.serialize(`KEYCLOAK_AWS_${tn}_EXPIRE`, '', { - path: '/', - expires: new Date(2671200000), - }), - }, - ], - }, - }; -} - -module.exports = { - tenantLogout, -}; diff --git a/src/edge/routes/routes.js b/src/edge/routes/routes.js deleted file mode 100644 index f133d40..0000000 --- a/src/edge/routes/routes.js +++ /dev/null @@ -1,142 +0,0 @@ -const { jwksUrl } = require('../../adapter/adapter'); - -const { tenantLogout } = require('./Logout'); -const { callbackHandler } = require('./Callback'); -const { lambdaEdgeRouteOptions } = require('../../utils/optionsUtils'); -const { registerRoute } = require('../router'); -const { - checkToken, - responseWithKeycloakRedirectToLoginPage, - refreshResponse, -} = require('./utils/redirectAuthServer'); - -async function isRequest(request, routePath, isRequestChecker = (r, rp, ret) => ret) { - const { uri } = request; - const ret = (routePath instanceof RegExp) ? !!uri.match(routePath) - : (uri.startsWith(`/${routePath}`) - || uri.startsWith(routePath)); - return isRequestChecker(request, routePath, ret); -} - -function defaultRegexRoute(url) { - return new RegExp(`(^)(\\/|)(${url})(/$|(\\?|$))`, 'g'); -} - -function addRoute(route) { - registerRoute(route); - console.log('added route'); -} - -function addUnProtected(routePath) { - console.log(`unprotected route ${routePath}`); - addRoute({ - isRoute: async (request) => await isRequest(request, routePath), - handle: async (request, config, callback) => { - callback(null, request); - }, - }); -} -function addJwksEndpoint(routePath, publicKey) { - console.log(`unprotected jwks endpoint route ${routePath}`); - addRoute({ - isRoute: async (request) => await isRequest(request, routePath), - handle: async (request, config, callback) => { - const response = { - status: '200', - body: jwksUrl(publicKey), - }; - callback(null, response); - }, - }); -} - -function addProtected(routePath, keycloakJson, options = {}) { - let kjson = keycloakJson; - let kjsonFunction = () => keycloakJson; - if (!keycloakJson) { - throw new Error('keycloak.json is empty'); - } - if (typeof keycloakJson === 'function') { - kjsonFunction = keycloakJson; - kjson = { realm: '{?realm?}', resource: '{?clientid?}' }; - } - - const newOptions = lambdaEdgeRouteOptions(options, keycloakJson); - // tenant logout - console.log(`tenant logout route /${kjson.realm}/${kjson.resource}/logout`); - addRoute({ - isRoute: async (request) => await isRequest(request, defaultRegexRoute(`/${kjsonFunction({ ...newOptions, request, routePath }).realm}/${kjsonFunction({ ...newOptions, request, routePath }).resource}/logout`)), - handle: async (request, config, callback, lambdaEdgeOptions) => { - const newOptions0 = { - ...lambdaEdgeOptions, ...newOptions, request, routePath, - }; - const response = await tenantLogout(request, newOptions0); - if (response) { - callback(null, response); - } - }, - }); - console.log(`tenant callback route /${kjson.realm}/${kjson.resource}/callback`); - // tenant callback - addRoute({ - isRoute: async (request) => await isRequest(request, defaultRegexRoute(`/${kjsonFunction({ ...newOptions, request, routePath }).realm}/${kjsonFunction({ ...newOptions, request, routePath }).resource}/callback`)), - handle: async (request, config, callback, lambdaEdgeOptions) => { - const newOptions0 = { - ...lambdaEdgeOptions, ...newOptions, request, routePath, - }; - const response = await callbackHandler(request, newOptions0, callback); - if (response) { - callback(null, response); - } - }, - }); - - console.log(`tenant refresh token route /${kjson.realm}/${kjson.resource}/refresh`); - // tenant refresh - addRoute({ - isRoute: async (request) => await isRequest(request, defaultRegexRoute(`/${kjsonFunction({ ...newOptions, request, routePath }).realm}/${kjsonFunction({ ...newOptions, request, routePath }).resource}/refresh`)), - handle: async (request, config, callback, lambdaEdgeOptions) => { - const newOptions0 = { - ...lambdaEdgeOptions, ...newOptions, request, routePath, - }; - let refreshToken = null; - const token = await checkToken(callback, newOptions0, - (refreshedToken) => { - refreshToken = refreshedToken.refresh_token; - }, responseWithKeycloakRedirectToLoginPage); - if (token) { - const response = refreshResponse(token, refreshToken, newOptions0); - callback(null, response); - } - }, - }); - const routes = Array.isArray(routePath) ? routePath : [routePath]; - routes.forEach((route) => { - console.log(`tenant route ${route}`); - // tenant protection - addRoute({ - isRoute: async (request) => await isRequest(request, route, options.isRequest), - handle: async (request, config, callback, lambdaEdgeOptions) => { - const newOptions0 = { - ...lambdaEdgeOptions, ...newOptions, request, routePath, - }; - const token = await checkToken(callback, newOptions0); - if (token) { - callback(null, - newOptions0.responseHandler - ? await Promise.resolve(newOptions0.responseHandler({ ...request, token }, - newOptions0)) - : request); - } - }, - }); - }); -} - -module.exports = { - addRoute, - addUnProtected, - addJwksEndpoint, - addProtected, - isRequest, -}; diff --git a/src/edge/routes/utils/nonce.js b/src/edge/routes/utils/nonce.js deleted file mode 100644 index 8bcef95..0000000 --- a/src/edge/routes/utils/nonce.js +++ /dev/null @@ -1,19 +0,0 @@ -const crypto = require('crypto'); - -function getNonce() { - const nonce = crypto.randomBytes(32) - .toString('hex'); - const hash = crypto.createHmac('sha256', nonce) - .digest('hex'); - return [nonce, hash]; -} - -function validateNonce(nonce, hash) { - const other = crypto.createHmac('sha256', nonce) - .digest('hex'); - return (other === hash); -} - -module.exports = { - getNonce, validateNonce, -}; diff --git a/src/edge/routes/utils/redirectAuthServer.js b/src/edge/routes/utils/redirectAuthServer.js deleted file mode 100644 index e4a14a1..0000000 --- a/src/edge/routes/utils/redirectAuthServer.js +++ /dev/null @@ -1,189 +0,0 @@ -const cookie = require('cookie'); -const qs = require('querystring'); - -const { getCookie, clearCookies } = require('../../../utils/cookiesUtils'); - -const { getActiveToken, decodeAccessToken } = require('../../../utils/TokenUtils'); -const { getKeycloakUrl } = require('../../../utils/restCalls'); - -const { getHostUrl, tenantName, signState } = require('../../lambdaEdgeUtils'); - -function buildUri(request) { - const queryDict = qs.parse(request.querystring); - if (queryDict.redirectUri) { - return queryDict.redirectUri; - } - return request.uri + (request.querystring ? `?${request.querystring}` : ''); -} - -function updateLoginLink(loginPage, options) { - if (options.updateLoginPage && options.updateLoginPage instanceof Function) { - return options.updateLoginPage(loginPage); - } - return loginPage; -} - -// eslint-disable-next-line import/prefer-default-export -async function redirectToKeycloak(request, options, url, callback) { - const host = getHostUrl(request); - const keycloakJson = options.keycloakJson(options); - options.logger.debug('Redirecting to OIDC provider.'); - const state = url || buildUri(request); - // if ( - // !state.includes('#') - // || !state.includes('?') - // || !state.includes('logout') - // || !state.includes('callback') - // ) { - // state = '/'; - // } - - const jwt = await signState(state, options); - const headers = { - location: [{ - key: 'Location', - value: updateLoginLink( - `${getKeycloakUrl(keycloakJson)}/realms/${keycloakJson.realm}/protocol/openid-connect/auth?client_id=${keycloakJson.resource}&redirect_uri=${encodeURIComponent(`${host}/${keycloakJson.realm}/${keycloakJson.resource}/callback`)}&state=${encodeURIComponent(jwt)}&response_type=code&scope=openid${options.kc_idp_hint ? `&kc_idp_hint=${options.kc_idp_hint}` : ''}`, - options, - ), - }], - 'set-cookie': [ - { - key: 'Set-Cookie', - value: cookie.serialize('SESSION_TOKEN', '', { - path: '/', - expires: new Date(2671200000), - }), - }, - ], - }; - callback(null, { - status: '302', - statusDescription: 'Found', - body: 'Redirecting to OIDC provider', - headers: clearCookies(request, options, headers), - }); -} - -async function responseWithKeycloakRedirectToLoginPage(request, options, url, callback) { - console.debug('Redirecting to OIDC provider.'); - const state = buildUri(request); - const jwt = await signState(state, options); - const host = getHostUrl(request); - const keycloakJson = options.keycloakJson(options); - const response = { - status: '200', - statusDescription: 'OK', - body: JSON.stringify({ - location: updateLoginLink(`${getKeycloakUrl(keycloakJson)}/realms/${keycloakJson.realm}/protocol/openid-connect/auth?client_id=${keycloakJson.resource}&redirect_uri=${encodeURIComponent(`${host}/${keycloakJson.realm}/${keycloakJson.resource}/callback`)}&state=${encodeURIComponent(jwt)}&response_type=code&scope=openid`, - options), - }), - headers: { - 'set-cookie': [ - { - key: 'Set-Cookie', - value: cookie.serialize(`KEYCLOAK_AWS_${tenantName(keycloakJson)}`, '', { - path: '/', - expires: new Date( - 1970, 1, 1, 0, 0, 0, 0, - ), - }), - }, - ], - }, - }; - callback(null, response); -} - -async function checkToken(callback, options, - refreshTokenHandler = () => {}, redirectToKeycloakAction = redirectToKeycloak) { - const { request } = options; - const keycloakJson = options.keycloakJson(options); - const cookieName = tenantName(keycloakJson); - const cookieHeader = getCookie(request, cookieName); - if (cookieHeader) { - const sessionString = cookieHeader.session; - const sessionTokenString = cookieHeader.sessionToken; - const decodedSession = sessionString ? decodeAccessToken(sessionString).accessTokenDecode : {}; - if (!await options.sessionManager.checkSession(sessionString) - // || !sessionTokenString - || !decodedSession.tenants - || !decodedSession.tenants[keycloakJson.realm] - || !decodedSession.tenants[keycloakJson.realm][keycloakJson.resource] - ) { - await redirectToKeycloakAction(request, options, null, callback); - } else { - try { - const token = await getActiveToken(sessionString, sessionTokenString, options, - refreshTokenHandler); - if (!token) { - await redirectToKeycloakAction(request, options, null, callback); - } else { - return { - access_token: token, - isChanged: token !== sessionTokenString, - }; - } - } catch (e) { - options.logger.error(`error=${e}`); - options.route.unauthorized( - e.message, e, '/', request, callback, - ); - } - } - } else { - await redirectToKeycloakAction(request, options, null, callback); - } - return null; -} - -function updateResponseHeaders(token, response, options) { - if (token.isChanged) { - const { accessTokenDecode } = decodeAccessToken(token); - if (!response.headers) { - response.headers = {}; - } - const { headers } = response; - if (!headers['set-cookie']) { - headers['set-cookie'] = []; - } - headers['set-cookie'].push({ - key: 'Set-Cookie', - value: cookie.serialize(`KEYCLOAK_AWS_${tenantName(options.keycloakJson(options))}`, token.access_token, { - path: '/', - expires: new Date((accessTokenDecode.exp - 30) * 1000), - }), - }); - } -} - -function refreshResponse(token, refreshToken, options) { - const response = { - status: '200', - statusDescription: 'OK', - }; - if (refreshToken) { - const refreshTokenDecode = decodeAccessToken(refreshToken).accessTokenDecode; - const s = tenantName(options.keycloakJson(options)); - response.headers = { - 'set-cookie': [ - { - key: 'Set-Cookie', - value: cookie.serialize(`KEYCLOAK_AWS_${s}_EXPIRE`, s, { - path: '/', - expires: new Date((refreshTokenDecode.exp) * 1000), - }), - }, - ], - }; - } - updateResponseHeaders(token, response, options); - return response; -} - -module.exports = { - redirectToKeycloak, - responseWithKeycloakRedirectToLoginPage, - checkToken, - refreshResponse, -}; diff --git a/src/edge/storage/SessionManager.js b/src/edge/storage/SessionManager.js deleted file mode 100644 index 28148cf..0000000 --- a/src/edge/storage/SessionManager.js +++ /dev/null @@ -1,210 +0,0 @@ -const jwt = require('jsonwebtoken'); - -const { tenantName } = require('../lambdaEdgeUtils'); - -const { decodeAccessToken } = require('../../utils/TokenUtils'); -const { clientJWT } = require('../../clientAuthorization'); - -function getSessionId(session) { - return jwt.decode(session).jti; -} - -function updateStorageToken(externalToken) { - const token = JSON.parse(JSON.stringify(externalToken)); - delete token.upgraded; - delete token.access_token; - delete token.expires_in; - delete token.refresh_expires_in; - delete token.token_type; - delete token.id_token; - delete token['not-before-policy']; - delete token.scope; - return token; -} - -function checkSession(sessionOptions) { - return async (sessionString) => { - if (!sessionString) { - return null; - } - const sessionJWT = jwt.decode(sessionString, { complete: true }); - if (!sessionJWT || !sessionJWT.header) { - throw new Error('invalid token (header part)'); - } else { - const { alg } = sessionJWT.header; - if (alg.toLowerCase() !== 'none' && !alg.toLowerCase().startsWith('hs')) { - try { - // const hostHeader = getHostHeader(request); - // if (hostHeader && hostHeader !== sessionJWT.payload.sub) { - // throw new Error(errorWithoutRefresh('invalid token')); - // } - // Verify and decode the token - const decoded = jwt.verify(sessionString, sessionOptions.keys.publicKey.key); - return decoded; - } catch (error) { - // Token is not valid - console.error(`invalid token ${error}`); - return null; - } - } else { - throw new Error('invalid token'); - } - } - }; -} - -async function createSessionToken(host, timeout, token, options) { - const decodedjwt = decodeAccessToken(token).accessTokenDecode; - const timeLocal = new Date().getTime(); - const timeSec = Math.floor(timeLocal / 1000); - const sessionId = decodedjwt.session_state; - const keycloakJson = options.keycloakJson(options); - const tn = tenantName(keycloakJson); - let payload = { - jti: decodedjwt.session_state, - sub: host, - exp: (timeSec + timeout), - email: decodedjwt.email, - upd: timeSec, - iat: timeSec, - }; - payload.tenants = {}; - payload.tenants[keycloakJson.realm] = {}; - payload.tenants[keycloakJson.realm][keycloakJson.resource] = { - cookieName: `KEYCLOAK_AWS_${tn}`, - session_state: decodedjwt.session_state, - route: options.routePath, - }; - if (options.sessionModify) { - const updatedPayload = await Promise.resolve( - options.sessionModify({ ...payload }, token, options), - ); - payload = { ...updatedPayload, ...payload }; - } - const session = await clientJWT(payload, options); - return { - sessionId, - session, - exp: payload.exp, - email: decodedjwt.email, - }; -} - -function createSession(sessionStorage, sessionOptions) { - return async (host, timeout, token, options) => { - const newOptions = { ...options, ...sessionOptions }; - const sessionObject = await createSessionToken(host, timeout, token, newOptions); - await sessionStorage.saveSession( - sessionObject.sessionId, - sessionObject.exp, - tenantName(newOptions.keycloakJson(options)), - updateStorageToken(token), - options, - ); - return sessionObject.session; - }; -} - -function getSessionIfExists(sessionStorage) { - return async (session, options) => sessionStorage - .getSessionIfExists( - getSessionId(session), options, - ); -} - -function deleteSession(sessionStorage) { - return async (session, options) => sessionStorage - .deleteSession( - getSessionId(session), options, - ); -} - -function deleteTenantSession(sessionStorage, sessionOptions) { - return async (session, options) => { - const newOptions = { ...options, ...sessionOptions }; - const keycloakJson = options.keycloakJson(newOptions); - let payload = jwt.decode(session); - if (options.sessionDelete) { - const updatedPayload = await Promise.resolve( - options.sessionDelete({ ...payload }, token, options), - ); - payload = { ...updatedPayload, ...payload }; - } - if (payload[keycloakJson.realm]) { - delete (payload[keycloakJson.realm])[keycloakJson.resource]; - } - const newSession = await clientJWT(payload, newOptions); - return { - sessionId: getSessionId(session), - session: newSession, - exp: payload.exp, - email: payload.email, - }; - }; -} - -async function updateSessionToken(session, token, options) { - const keycloakJson = options.keycloakJson(options); - let payload = jwt.decode(session); - const sessionId = getSessionId(session); - let newSession = session; - if (!(payload.tenants - && payload.tenants[keycloakJson.realm] - && payload.tenants[keycloakJson.resource])) { - const tn = tenantName(keycloakJson); - const timeLocal = new Date().getTime(); - payload.upd = Math.floor(timeLocal / 1000); - payload.tenants = payload.tenants || {}; - payload.tenants[keycloakJson.realm] = payload.tenants[keycloakJson.realm] || {}; - payload.tenants[keycloakJson.realm][keycloakJson.resource] = { - cookieName: `KEYCLOAK_AWS_${tn}`, - session_state: token.session_state, - route: options.routePath, - }; - if (options.sessionModify) { - const updatedPayload = await Promise.resolve( - options.sessionModify({ ...payload }, token, options), - ); - payload = { ...updatedPayload, ...payload }; - } - newSession = await clientJWT(payload, options); - } - return { - sessionId, - session: newSession, - exp: payload.exp, - email: payload.email, - }; -} - -function modifySession(sessionStorage, sessionOptions) { - return async (session, token, options) => { - const newOptions = { ...options, ...sessionOptions }; - const sessionObject = await updateSessionToken(session, token, newOptions); - return sessionObject.session; - }; -} -function updateSession(sessionStorage) { - return async (session, tenant, token, options) => { - await sessionStorage - .updateSession(getSessionId(session), tenant, updateStorageToken(token), options); - }; -} - -function SessionManager(sessionStorage, sessionOptions) { - return { - sessionStorage, - checkSession: checkSession(sessionOptions), - sessionOptions, - getSessionIfExists: getSessionIfExists(sessionStorage), - updateSession: updateSession(sessionStorage, sessionOptions), - updateSessionToken: modifySession(sessionStorage, sessionOptions), - deleteSession: deleteSession(sessionStorage), - deleteTenantSession: deleteTenantSession(sessionStorage, sessionOptions), - createSession: createSession(sessionStorage, sessionOptions), - }; -} - -module.exports = { - SessionManager, -}; diff --git a/src/edge/storage/localSessionStorage.js b/src/edge/storage/localSessionStorage.js deleted file mode 100644 index 692e1b9..0000000 --- a/src/edge/storage/localSessionStorage.js +++ /dev/null @@ -1,94 +0,0 @@ -const fs = require('fs'); - -async function readStorage() { - try { - return (await fs.promises.readFile('./storage.json')).toString('utf8'); - } catch (e) { - if (e.code === 'ENOENT') { - console.log('Expected storage.json to be included in Lambda deployment package'); - // fallthrough - } - return '{}'; - } -} - -async function saveStorage(storage) { - try { - await fs.promises.writeFile('./storage.json', JSON.stringify(storage)); - } catch (e) { - if (e.code === 'ENOENT') { - console.log('Expected storage.json to be included in Lambda deployment package'); - // fallthrough - } - throw new Error(e); - } -} - -async function updateStorage() { - const timeLocal = new Date().getTime(); - const timeSec = Math.floor(timeLocal / 1000); - const jsonFile = await readStorage(); - const json = JSON.parse(jsonFile); - Object.keys(json).forEach((sessionId) => { - const { exp } = json[sessionId]; - if (exp < timeSec) { - delete json[sessionId]; - } - }); - await saveStorage(json); - return json; -} - -async function saveSession( - sessionId, - exp, - tenant, - externalToken, -) { - const tenantJson = { - session: sessionId, - exp, - }; - const inMemory = await updateStorage(); - tenantJson[tenant] = externalToken; - inMemory[sessionId] = tenantJson; - await saveStorage(inMemory); -} - -async function updateSession(sessionId, tenant, externalToken) { - const inMemory = await updateStorage(); - const sessionObject = inMemory[sessionId]; - if (sessionObject) { - sessionObject[tenant] = externalToken; - } else { - const json = { - session: sessionId, - }; - json[tenant] = externalToken; - inMemory[sessionId] = json; - } - await saveStorage(inMemory); -} - -async function getSessionIfExists(session) { - const inMemory = await updateStorage(); - return inMemory[session]; -} - -async function deleteSession(session) { - const inMemory = await updateStorage(); - delete inMemory[session]; -} - -function LocalSessionStorage() { - return { - saveSession, - updateSession, - getSessionIfExists, - deleteSession, - }; -} - -module.exports = { - LocalSessionStorage, -}; diff --git a/src/utils/CustomPageUtils.js b/src/utils/CustomPageUtils.js deleted file mode 100644 index 32aabaa..0000000 --- a/src/utils/CustomPageUtils.js +++ /dev/null @@ -1,72 +0,0 @@ -const { getCookies } = require('./cookiesUtils'); -const { getHostUrl } = require('../edge/lambdaEdgeUtils'); - -function unauthorized( - error, errorDescription, errorUri, request, callback, -) { - let page = ` - - - - - - We've got some trouble | 401 - Unauthorized - - - -

%error% Error 401

%error_description%

%error_uri%

- - - - `; - - page = page.replace(/%error%/g, error); - page = page.replace(/%error_description%/g, errorDescription); - page = page.replace(/%error_uri%/g, errorUri); - - // Unauthorized access attempt. Reset token and nonce cookies - const response = { - status: '401', - statusDescription: 'Unauthorized', - body: page, - headers: getCookies(request, { - 'set-cookie': [ - ], - }), - }; - callback(null, response); -} - -function internalServerError(request, callback) { - const page = ` - - - - - - We've got some trouble | 500 - Internal Server Error - - - -

Internal Server Error Error 500

- - - - `; - - const response = { - status: '500', - statusDescription: 'Internal Server Error', - body: page, - headers: getCookies(request, { - 'set-cookie': [ - ], - }), - }; - callback(null, response); -} - -module.exports = { - internalServerError, - unauthorized, -}; diff --git a/src/utils/TokenUtils.js b/src/utils/TokenUtils.js index 0d772ea..2ead14d 100644 --- a/src/utils/TokenUtils.js +++ b/src/utils/TokenUtils.js @@ -2,7 +2,6 @@ const jwt = require('jsonwebtoken'); const { lambdaAdapter } = require('../adapter/adapter'); const { keycloakRefreshToken } = require('../clientAuthorization'); -const { tenantName } = require('../edge/lambdaEdgeUtils'); function decodeAccessToken(externalToken) { const token = externalToken.access_token ? externalToken.access_token : externalToken; @@ -21,41 +20,7 @@ async function tokenIsValid(token, options) { } } -async function getActiveToken(session, accessToken, options, refreshTokenHandler) { - try { - await lambdaAdapter(decodeAccessToken(accessToken).accessToken, - options.keycloakJson, - options); - return accessToken; - } catch (e1) { - const sessionStorageItem = await options.sessionManager.getSessionIfExists(session, options); - if (sessionStorageItem) { - const tn = tenantName(options.keycloakJson(options)); - const externalToken = sessionStorageItem[tn]; - try { - const token = await keycloakRefreshToken(externalToken, options); - if (!token) { - return null; - } - if (refreshTokenHandler) { - refreshTokenHandler(token); - } - await options.sessionManager.updateSession(session, - tn, - token, options); - return token.access_token; - } catch (ex) { - throw new Error(ex); - } - } else { - options.logger.error(`Session does not exist: ${JSON.stringify(session)}`); - return null; - } - } -} - module.exports = { decodeAccessToken, tokenIsValid, - getActiveToken, }; diff --git a/src/utils/cookiesUtils.js b/src/utils/cookiesUtils.js deleted file mode 100644 index 9da1a00..0000000 --- a/src/utils/cookiesUtils.js +++ /dev/null @@ -1,65 +0,0 @@ -const cookie = require('cookie'); - -const { tenantName } = require('../edge/lambdaEdgeUtils'); - -function getCookies(request, responseHeaders = {}) { - const { headers } = request; - const newResponseHeaders = { ...responseHeaders }; - if (!newResponseHeaders['set-cookie']) { - newResponseHeaders['set-cookie'] = []; - } - if ('cookie' in headers) { - const cookieJson = cookie.parse(headers.cookie[0].value); - Object.keys(cookieJson).filter((field) => field.startsWith('KEYCLOAK_AWS')).forEach((header) => { - newResponseHeaders['set-cookie'].push({ - key: 'Set-Cookie', - value: cookie.serialize(header, '', { - path: '/', - expires: new Date(2671200000), - }), - }); - }); - } - return newResponseHeaders; -} - -function clearCookies(request, options, responseHeaders = {}) { - const { headers } = request; - const newResponseHeaders = { ...responseHeaders }; - if (!newResponseHeaders['set-cookie']) { - newResponseHeaders['set-cookie'] = []; - } - if ('cookie' in headers) { - const cookieJson = cookie.parse(headers.cookie[0].value); - Object.keys(cookieJson).filter((field) => field.startsWith(`KEYCLOAK_AWS_${tenantName(options.keycloakJson(options))}`)).forEach((header) => { - newResponseHeaders['set-cookie'].push({ - key: 'Set-Cookie', - value: cookie.serialize(header, '', { - path: '/', - expires: new Date(2671200000), - }), - }); - }); - } - return newResponseHeaders; -} - -function getCookie(request, cookieName = 'SESSION') { - const s = `KEYCLOAK_AWS_${cookieName}`; - const { headers } = request; - if ('cookie' in headers - && 'KEYCLOAK_AWS_SESSION' in cookie.parse(headers.cookie[0].value)) { - const cookieJson = cookie.parse(headers.cookie[0].value); - return { - session: cookieJson.KEYCLOAK_AWS_SESSION, - sessionToken: cookieJson[s], - }; - } - return null; -} - -module.exports = { - getCookies, - getCookie, - clearCookies, -}; diff --git a/src/utils/optionsUtils.js b/src/utils/optionsUtils.js index 2e2bc14..1805b1a 100644 --- a/src/utils/optionsUtils.js +++ b/src/utils/optionsUtils.js @@ -1,5 +1,3 @@ -const { unauthorized, internalServerError } = require('./CustomPageUtils'); - const defaultCache = require('../cache/NodeCacheImpl'); const defaultEnforcer = { @@ -51,27 +49,6 @@ function commonOptions(options, keycloakJson) { }; } -function lambdaEdgeRouteOptions(options = {}, keycloakJson) { - const route = options.route || {}; - return { - ...commonOptions(options, keycloakJson), - ...{ - updateLoginPage: options.updateLoginPage || function (url) { return url; }, - route: { - unauthorized: route.unauthorized || unauthorized, - internalServerError: route.internalServerError || internalServerError, - - }, - }, - }; -} - -function lambdaEdgeOptions(sessionManager) { - return { ...lambdaEdgeRouteOptions(sessionManager.sessionOptions), sessionManager }; -} - module.exports = { commonOptions, - lambdaEdgeOptions, - lambdaEdgeRouteOptions, }; From 9d4c7f7e099d95d25d30ebcde9db469192433ee4 Mon Sep 17 00:00:00 2001 From: vzakharchenko Date: Wed, 7 Jul 2021 22:13:53 +0300 Subject: [PATCH 2/7] moved lambda@edge to https://github.com/vzakharchenko/keycloak-api-gateway --- .github/workflows/nodejs.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 3f9cbd7..6cc984a 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -33,14 +33,6 @@ jobs: - run: cd example/keycloak-authorizer/serverless-jwks && npm run lint - run: cd example/keycloak-authorizer/ui && npm i - run: cd example/keycloak-authorizer/ui && npm run lint - - run: cd example/keycloak-cloudfront/keycloak-cloudfront-cdk && npm i - - run: cd example/keycloak-cloudfront/lambda-edge-example && npm i && npm run build - - run: cd example/keycloak-cloudfront && npm i && npm run build - - run: cd example/keycloak-cloudfront && npm run lint - - run: cd example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk && npm i - - run: cd example/keycloak-cloudfront-portal/lambda-edge-example && npm i && npm run build - - run: cd example/keycloak-cloudfront-portal && npm i && npm run build - - run: cd example/keycloak-cloudfront-portal && npm run lint - run: cd example/chain-service-calls/frontend && npm i && npm run lint - run: cd example/chain-service-calls/service1 && npm i && npm run lint - run: cd example/chain-service-calls/service2 && npm i && npm run lint From dfeea0804384a1e4e29e141ea1e6136acdf6b0be Mon Sep 17 00:00:00 2001 From: vzakharchenko Date: Wed, 7 Jul 2021 22:14:49 +0300 Subject: [PATCH 3/7] update dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index be3ee1d..87ed812 100644 --- a/package.json +++ b/package.json @@ -59,11 +59,11 @@ "@babel/polyfill": "^7.12.1", "@babel/runtime": "^7.14.6", "babel-eslint": "^10.1.0", - "coveralls": "^3.1.0", - "eslint": "^7.28.0", + "coveralls": "^3.1.1", + "eslint": "^7.30.0", "eslint-config-airbnb": "^18.2.1", "eslint-plugin-import": "^2.23.4", - "jest": "^27.0.4" + "jest": "^27.0.6" }, "dependencies": { "aws-arn-parser": "^1.0.1", From d26473d4505873f0caa2df7689ab4fbc0b8ea7fd Mon Sep 17 00:00:00 2001 From: vzakharchenko Date: Wed, 7 Jul 2021 22:16:11 +0300 Subject: [PATCH 4/7] update dependencies --- .github/workflows/nodejs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 6cc984a..03db5fd 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -24,7 +24,7 @@ jobs: uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - - run: npm i && cd keycloak-cloudfront-dynamodb && npm i + - run: npm i - run: npm run lint - run: npm run test - run: cd example/keycloak-authorizer/serverless && npm i From 7c8c999a5a6ef43d27387c339a1ddde9d7c4caf1 Mon Sep 17 00:00:00 2001 From: vzakharchenko Date: Wed, 7 Jul 2021 22:21:00 +0300 Subject: [PATCH 5/7] update dependencies --- .github/workflows/nodejs.yml | 2 +- index.js | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 03db5fd..8975d8a 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -24,7 +24,7 @@ jobs: uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - - run: npm i + - run: npm i - run: npm run lint - run: npm run test - run: cd example/keycloak-authorizer/serverless && npm i diff --git a/index.js b/index.js index 17c05e9..bedea8f 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,7 @@ const apigateway = require('./src/apigateway/apigateway'); const adapter = require('./src/adapter/adapter'); const { middlewareAdapter } = require('./src/adapter/middlewareAdapter'); -const lamdaEdge = require('./src/edge/lamdaEdge'); module.exports = { - apigateway, adapter, lamdaEdge, middlewareAdapter, + apigateway, adapter, middlewareAdapter, }; From 99a8581c206463c12f25dd3fd29f901e7819372d Mon Sep 17 00:00:00 2001 From: vzakharchenko Date: Wed, 7 Jul 2021 22:23:00 +0300 Subject: [PATCH 6/7] moved lambda@edge to https://github.com/vzakharchenko/keycloak-api-gateway --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 87ed812..cfcc9b4 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,8 @@ }, "scripts": { "test": "jest --verbose --maxWorkers=2 --coverage --coverageDirectory=.coverage/", - "lint": "eslint --quiet --ext .js index.js && eslint --quiet --ext .js src keycloak-cloudfront-dynamodb/DynamoDbSessionStorage.js", - "lint:fix": "eslint --fix --quiet --ext .js index.js && eslint --fix --quiet --ext .js src __tests__ keycloak-cloudfront-dynamodb/DynamoDbSessionStorage.js" + "lint": "eslint --quiet --ext .js index.js && eslint --quiet --ext .js src", + "lint:fix": "eslint --fix --quiet --ext .js index.js && eslint --fix --quiet --ext .js src __tests__" }, "repository": { "type": "git", From 26aa4818c93e428b583bff4548ad54255cbab44f Mon Sep 17 00:00:00 2001 From: vzakharchenko Date: Wed, 7 Jul 2021 22:26:23 +0300 Subject: [PATCH 7/7] fix circle-CI --- .circleci/config.yml | 26 +------------------------- package.json | 2 +- 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c8855c3..5729f93 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,7 +12,7 @@ jobs: - run: name: build source - command: npm i && cd keycloak-cloudfront-dynamodb && npm i + command: npm i - run: name: lint command: npm run lint @@ -42,30 +42,6 @@ jobs: - run: name: lint example/keycloak-authorizer ui command: cd example/keycloak-authorizer/ui && npm run lint - - run: - name: build example/keycloak-cloudfront cloudfront-cdk - command: cd example/keycloak-cloudfront/keycloak-cloudfront-cdk && npm i - - run: - name: build example/keycloak-cloudfront lambda-edge-example - command: cd example/keycloak-cloudfront/lambda-edge-example && npm i && npm run build - - run: - name: build example/keycloak-cloudfront cloudfront - command: cd example/keycloak-cloudfront && npm i && npm run build - - run: - name: lint example/keycloak-cloudfront cloudfront - command: cd example/keycloak-cloudfront && npm run lint - - run: - name: build example/keycloak-cloudfront-portal cloudfront-cdk - command: cd example/keycloak-cloudfront-portal/keycloak-cloudfront-cdk && npm i - - run: - name: build example/keycloak-cloudfront-portal lambda-edge-example - command: cd example/keycloak-cloudfront-portal/lambda-edge-example && npm i && npm run build - - run: - name: build example/keycloak-cloudfront-portal cloudfront - command: cd example/keycloak-cloudfront-portal && npm i && npm run build - - run: - name: lint example/keycloak-cloudfront-portal cloudfront - command: cd example/keycloak-cloudfront-portal && npm run lint - run: name: lint example/chain-service-calls/frontend command: cd example/chain-service-calls/frontend && npm i && npm run lint diff --git a/package.json b/package.json index cfcc9b4..e211596 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keycloak-lambda-authorizer", - "version": "0.5.2", + "version": "0.6.0", "description": "Keycloak Cloud Adapter", "main": "index.js", "homepage": "https://github.com/vzakharchenko/keycloak-lambda-authorizer",