Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
vzakharchenko
committed
Jun 2, 2020
1 parent
289bbc8
commit d6e83a2
Showing
24 changed files
with
7,215 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Cloudfront(Lambda:edge) with portal authorization | ||
|
||
## 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 SecurityRealm1: | ||
replace with http://<YOUR DEVICE IP>:8080/cert instead of http://localhost:8080/cert | ||
change JWKS URL for SecurityRealm2: | ||
replace with http://<YOUR DEVICE IP>: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 portal.realm, realm1.json and realm2.json and click Create. | ||
** | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
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, | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<title>CloudFront/Lambda:edge example</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
</body> | ||
</html> |
33 changes: 33 additions & 0 deletions
33
example/keycloak-cloudfront-portal/lambda-edge-example/babel.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
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, | ||
}; | ||
}; |
4 changes: 4 additions & 0 deletions
4
example/keycloak-cloudfront-portal/lambda-edge-example/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { authorization } from './src/index'; | ||
|
||
// eslint-disable-next-line import/prefer-default-export | ||
export const lambda = authorization; |
7 changes: 7 additions & 0 deletions
7
example/keycloak-cloudfront-portal/lambda-edge-example/jest.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module.exports = { | ||
setupFiles: ['./unitTestConfig/jestSetup.js'], | ||
transform: { | ||
'^.+\\.js$': 'babel-jest', | ||
}, | ||
transformIgnorePatterns: ['<rootDir>/node_modules/'], | ||
}; |
45 changes: 45 additions & 0 deletions
45
example/keycloak-cloudfront-portal/lambda-edge-example/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
{ | ||
"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.10.2", | ||
"@babel/plugin-proposal-decorators": "^7.10.1", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.10.1", | ||
"@babel/plugin-transform-runtime": "^7.10.1", | ||
"@babel/preset-env": "^7.10.2", | ||
"@babel/register": "^7.10.1", | ||
"babel-jest": "^26.0.1", | ||
"babel-loader": "^8.1.0", | ||
"enzyme": "^3.11.0", | ||
"jest": "^26.0.1", | ||
"jest-date-mock": "^1.0.8", | ||
"progress-bar-webpack-plugin": "^2.1.0", | ||
"uglifyjs-webpack-plugin": "^2.2.0", | ||
"webpack": "^4.43.0", | ||
"webpack-cli": "^3.3.11" | ||
}, | ||
"dependencies": { | ||
"@babel/runtime": "^7.10.2", | ||
"axios": "^0.19.2", | ||
"cookie": "^0.4.1", | ||
"crypto-js": "^4.0.0", | ||
"jsonwebtoken": "^8.5.1", | ||
"jws": "^4.0.0", | ||
"keycloak-lambda-authorizer": "../../../", | ||
"node-cache": "^5.1.0", | ||
"node-forge": "^0.9.1", | ||
"querystring": "^0.2.0", | ||
"rsa-pem-to-jwk": "^1.1.3", | ||
"keycloak-cloudfront-dynamodb": "^0.1.4", | ||
"uuid": "^8.1.0" | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
example/keycloak-cloudfront-portal/lambda-edge-example/src/Tentants.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { privateKey, publicKey } from './sessionKeys'; | ||
|
||
export const portalKeycloakJSON = { | ||
realm: 'portal', | ||
'auth-server-url': 'http://127.0.0.1:8090/auth/', | ||
'ssl-required': 'external', | ||
resource: 'portal-ui', | ||
credentials: { | ||
secret: 'ece2012c-fc01-4dca-b50b-f898c9c6c811', | ||
}, | ||
'confidential-port': 0, | ||
}; | ||
|
||
export const tenant1KeycloakJson = { | ||
realm: 'securityRealm2', | ||
'auth-server-url': 'http://localhost:8090/auth/', | ||
'ssl-required': 'external', | ||
resource: 'tenant1Client', | ||
'verify-token-audience': true, | ||
credentials: { | ||
jwt: { }, | ||
}, | ||
'confidential-port': 0, | ||
'policy-enforcer': {}, | ||
}; | ||
|
||
export const tenant1Options = { | ||
enforce: { | ||
enabled: true, | ||
resource: { | ||
name: 'tenant1Resource', | ||
}, | ||
}, | ||
}; | ||
|
||
|
||
export const tenant2KeycloakJson = { | ||
realm: 'securityRealm2', | ||
'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', | ||
}, | ||
}, | ||
}; |
76 changes: 76 additions & 0 deletions
76
example/keycloak-cloudfront-portal/lambda-edge-example/src/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
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, | ||
portalKeycloakJSON, | ||
} 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 }, | ||
}, | ||
); | ||
lamdaEdge.routes.addProtected( | ||
['/', keycloakJson1.realm], | ||
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); | ||
} |
60 changes: 60 additions & 0 deletions
60
example/keycloak-cloudfront-portal/lambda-edge-example/src/sessionKeys.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
|
||
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, | ||
}, | ||
}; |
Oops, something went wrong.