Ory Hydra Authorization Code Exchange => access token Use openid-client

https://github.com/panva/node-openid-client/tree/v2.x Important! WARNING: Node.js 12 or higher is required for openid-client@3 and above. For older Node.js versions use openid-client@2. So watch https://github.com/panva/node-openid-client/tree/v2.x node.js package use “openid-client”: “2.5.0”, client.authorizationCallback have bug, nonce mismatch always have this error even see https://github.com/panva/node-openid-client/issues/150 Correct way https://github.com/panva/node-openid-client/blob/f1b4282ac50f7e15fc195f66bf76409af4ec4b6b/lib/client.js see if (params.code) { Can know use grant https://github.com/panva/node-openid-client/tree/v2.x#custom-token-endpoint-grants const hydraconfig= { "oidurl": "https://openid.hydra:9001", "redirectUri": "https://t.tt:9010/callback", "clientid": "auth-code-client", "clientsecretid": "secret" } //openid-client================ const { Issuer } = require('openid-client') const hydraIssuer = await Issuer.discover(hydraconfig.oidurl) // => Promise .then(function (hydradiscoverIssuer) { console.log('Discovered issuer %s %O', hydradiscoverIssuer.issuer, hydradiscoverIssuer.metadata); return hydradiscoverIssuer }); const client = new hydraIssuer.Client({ client_id: hydraconfig.clientid, client_secret: hydraconfig.clientsecretid }); var tokenset = await client.grant({ grant_type: 'authorization_code', code: code, redirect_uri: hydraconfig.redirectUri, code_verifier: '', //No value, because real use in Hydra login-consent. Not use client.authorizationUrl or client.authorizationPost }); console.log(tokenset)

2019-08-07 · 1 min · 128 words · Me

Ory Hydra Authorization Code Exchange => access token

Before posts about Hydra get access token is use golang HydraOauthConfig.Exchange(ctx, code). This is easy way. But on front website like vue or other framework how to get access token. Use REST Client to test POST https://openid.hydra:9001/oauth2/token Authorization: Basic YXV0aC1jb2RlLWNsaWVudDpzZWNyZXQ= Content-Type: application/x-www-form-urlencoded grant_type=authorization_code &code=cuNw76aEuckIJJyVssk2LJvqdLXffT-8Kx1s0tYFt6Y.v0Dxc2_yT9ga8c2moKx0fDbwRFVgwryAt5BJM7lOJlM #&redirect_uri=https://certfront/oid/test/callback #&scope=openid,offline #&client_id=auth-code-client #&code_verifier= #&state=gczxkznmjkrksgytsemvwgkf Import is: Authorization: Basic https://github.com/ory/hydra/issues/631 Not Authorization: Bearer base64(urlencode(client_id):urlencode(client_secret)) YXV0aC1jb2RlLWNsaWVudDpzZWNyZXQ= => auth-code-client:secret code is callback code. When you login-consent finish step then callback to your set callback URL. Watch URL inside have code= example: https://t.tt:9010/callback?code=cuNw76aEuckIJJyVssk2LJvqdLXffT-8Kx1s0tYFt6Y.v0Dxc2_yT9ga8c2moKx0fDbwRFVgwryAt5BJM7lOJlM&scope=openid%20offline&state=gczxkznmjkrksgytsemvwgkf ...

2019-08-07 · 1 min · 159 words · Me

[轉]如何使用 OpenSSL 建立開發測試用途的自簽憑證 (Self-Signed Certificate)

https://blog.miniasp.com/post/2019/02/25/Creating-Self-signed-Certificate-using-OpenSSL 目前這個方式比較靠普 建立 ssl.conf 設定檔 [req] prompt = no default_md = sha256 default_bits = 2048 distinguished_name = dn x509_extensions = v3_req [dn] C = TW ST = Taiwan L = Taipei O = Duotify Inc. OU = IT Department emailAddress = admin@example.com CN = localhost [v3_req] subjectAltName = @alt_names [alt_names] DNS.1 = *.localhost DNS.2 = localhost DNS.3 = 192.168.2.100 openssl req -x509 -new -nodes -sha256 -utf8 -days 3650 -newkey rsa:2048 -keyout server.key -out server.crt -config ssl.conf

2019-08-06 · 1 min · 76 words · Me

OpenID hydra docker-compose hydra-login-consent-node mariadb

docker-compose version: '3.3' services: ory-hydra-postgres: image: postgres:9.6 #restart: always environment: - POSTGRES_USER=hydra - POSTGRES_PASSWORD=secret - POSTGRES_DB=hydra volumes: - hydradata:/var/lib/postgresql/data:rw networks: - openid # 第一次執行postgres要做資料庫格式建立 PS: network依佈屬環境為主 docker network ls 確認 # docker run -it --rm \ # --network openid \ # oryd/hydra:latest \ # migrate sql --yes postgres://hydra:secret@ory-hydra-postgres:5432/hydra?sslmode=disable ory-hydra: image: oryd/hydra:latest restart: unless-stopped ports: - "9001:4444" - "9002:4445" environment: - SECRETS_SYSTEM=this_needs_to_be_the_same_a - DSN=postgres://hydra:secret@ory-hydra-postgres:5432/hydra?sslmode=disable - URLS_SELF_ISSUER=https://openid.hydra:9001/ - URLS_CONSENT=http://192.168.99.100:9020/consent - URLS_LOGIN=http://192.168.99.100:9020/login - LOG_LEVEL=debug - OAUTH2_EXPOSE_INTERNAL_ERRORS=true - SERVE_PUBLIC_CORS_ENABLED=true - SERVE_PUBLIC_CORS_ALLOWED_METHODS=POST,GET,PUT,DELETE - SERVE_ADMIN_CORS_ENABLED=true - SERVE_ADMIN_CORS_ALLOWED_METHODS=POST,GET,PUT,DELETE - SERVE_TLS_KEY_BASE64=LS0tLS1CRUdJTiBFQyBQQVJBTUVURVJTLS0tLS0KQmdVcmdRUUFJZz09Ci0tLS0tRU5EIEVDIFBBUkFNRVRFUlMtLS0tLQotLS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS0KTUlHa0FnRUJCRENLbkdnVnFJVzdZaW5iUWV5UEd5UTQ0R3U2VVFEelU5SENLYjMzTWlmeFJYRTBkbnU2KzdadQowdEJUcUhQRHVMeWdCd1lGSzRFRUFDS2haQU5pQUFSbng1Nk9jeGNyRWRsYmU4TXRSdUVxWGV2OEREcmh6ZWJGCjM4NlI4Q2RQWDRlUWI2Zll6ekFUL3V3STBsTDdvRmlEWEM3Q0JLWmZUcTdFSzN4TzNXWlpSSjJrMEQ3TnNLd2cKVEpZenJxT0JpczBNeGtva2FUWVVyemhKMXBKY3lmWT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo= - SERVE_TLS_CERT_BASE64=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNQVENDQWNLZ0F3SUJBZ0lKQU13RjRiVDRvSnh0TUFvR0NDcUdTTTQ5QkFNQ01Gd3hDekFKQmdOVkJBWVQKQWtGVk1STXdFUVlEVlFRSURBcFRiMjFsTFZOMFlYUmxNU0V3SHdZRFZRUUtEQmhKYm5SbGNtNWxkQ0JYYVdSbgphWFJ6SUZCMGVTQk1kR1F4RlRBVEJnTlZCQU1NREc5d1pXNXBaQzVvZVdSeVlUQWVGdzB4T1RBMk1UY3dNVEl4Ck16ZGFGdzB5T1RBMk1UUXdNVEl4TXpkYU1Gd3hDekFKQmdOVkJBWVRBa0ZWTVJNd0VRWURWUVFJREFwVGIyMWwKTFZOMFlYUmxNU0V3SHdZRFZRUUtEQmhKYm5SbGNtNWxkQ0JYYVdSbmFYUnpJRkIwZVNCTWRHUXhGVEFUQmdOVgpCQU1NREc5d1pXNXBaQzVvZVdSeVlUQjJNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWlBMklBQkdmSG5vNXpGeXNSCjJWdDd3eTFHNFNwZDYvd01PdUhONXNYZnpwSHdKMDlmaDVCdnA5alBNQlArN0FqU1V2dWdXSU5jTHNJRXBsOU8KcnNRcmZFN2RabGxFbmFUUVBzMndyQ0JNbGpPdW80R0t6UXpHU2lScE5oU3ZPRW5Xa2x6SjlxTlFNRTR3SFFZRApWUjBPQkJZRUZHK3Z6ZkIxYmVnM1VadEpYRXZWOWRNa1hvNmdNQjhHQTFVZEl3UVlNQmFBRkcrdnpmQjFiZWczClVadEpYRXZWOWRNa1hvNmdNQXdHQTFVZEV3UUZNQU1CQWY4d0NnWUlLb1pJemowRUF3SURhUUF3WmdJeEFMUHYKODZFSFRUVElLcEJHdlQrY2NWN3djSC84SFIrc2xhZC9ZUFhLUlZwd2RDbzUyZVRPV3BDS2dGamtHNEJhd1FJeApBTGxGZFgwbEk2ZzhXS3lhRTVmKzJGZEkxYWVqQ0Ftd0xPTTZTRFJhNFVHbitDa2VwOEljeG1CTDIvQmUzSVZ6CjhnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= networks: - openid # 快速建立 auth-doce-client PS: network依佈屬環境為主 docker network ls 確認 #docker run --rm -it \ # -e HYDRA_ADMIN_URL=https://ory-hydra:4445 \ # --network openid \ # oryd/hydra:latest \ # clients create --skip-tls-verify \ # --id auth-code-client \ # --secret secret \ # --grant-types authorization_code,refresh_token \ # --response-types code,id_token,token \ # --scope openid,offline,photos.read \ # --callbacks https://t.tt:9010/callback ory-hydra-login-consent: #image: oryd/hydra-login-consent-node:latest build: context: hydra-login-consent-node/ restart: unless-stopped ports: - "9020:3000" environment: - HYDRA_ADMIN_URL=https://ory-hydra:4445 - NODE_TLS_REJECT_UNAUTHORIZED=0 volumes: - hydraloginconsent:/usr/src/app:rw depends_on: - mariadb networks: - openid mariadb: image: mariadb:10.4.6 #restart: always environment: - MYSQL_ROOT_PASSWORD=secret - MYSQL_DATABASE=openid command: ['--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci'] #第一次使執行db_init_sql.txt networks: - openid adminer: image: adminer restart: always ports: - 8080:8080 depends_on: - mariadb networks: - openid volumes: hydradata: hydraloginconsent: networks: openid: driver: bridge Use adminer test maraidb: http://192.168.99.100:8080 root/secret mariadb init DROP DATABASE IF EXISTS `openid`; CREATE DATABASE `openid` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */; USE `openid`; DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` text COLLATE utf8mb4_unicode_ci NOT NULL, `email` text COLLATE utf8mb4_unicode_ci NOT NULL, `password` text COLLATE utf8mb4_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; INSERT INTO `user` (`id`, `name`, `email`, `password`) VALUES (1, 'foobar', 'foo@bar.com', '3858f62230ac3c915f300c664312c63f'); ory-hydra-login-consent modify package.json add "md5": "^2.2.1", "mysql": "^2.17.1" ory-hydra-login-consent add db/database.js var mysql = require('mysql'); var pool = mysql.createPool({ host : 'mariadb', user : 'root', password : 'secret', database: 'openid' }); var query=function(sql,options,callback){ pool.getConnection(function(err,conn){ pool.query if(err){ callback(err,null,null); }else{ conn.query(sql,options,function(err,results,fields){ //释放连接 conn.release(); //事件驱动回调 callback(err,results,fields); }); } }); }; module.exports = {query, pool} ory-hydra-login-consent modify routes/login.js ... router.post('/', csrfProtection, function (req, res, next) { // The challenge is now a hidden input field, so let's take it from the request body instead var challenge = req.body.challenge; var sql = "select count(*) as count from user where email = ? and password = ?" var params = [req.body.email, md5(req.body.password)] //db.get(sql, params, (err, row) => { pool.query(sql, params, (err, row) => { if (err) { res.status(400).json({"db error":err.message}); return; } if(!(row.count==1)){ //找不到 res.render('login', { csrfToken: req.csrfToken(), challenge: challenge, error: 'The username / password combination is not correct' }); return; } hydra.acceptLoginRequest(challenge, { // Subject is an alias for user ID. A subject can be a random string, a UUID, an email address, .... subject: req.body.email, // This tells hydra to remember the browser and automatically authenticate the user in future requests. This will // set the "skip" parameter in the other route to true on subsequent requests! remember: Boolean(req.body.remember), // When the session expires, in seconds. Set this to 0 so it will never expire. remember_for: 3600, // Sets which "level" (e.g. 2-factor authentication) of authentication the user has. The value is really arbitrary // and optional. In the context of OpenID Connect, a value of 0 indicates the lowest authorization level. // acr: '0', }) .then(function (response) { // All we need to do now is to redirect the user back to hydra! res.redirect(response.redirect_to); }) // This will handle any error that happens when making HTTP calls to hydra .catch(function (error) { next(error); }); }); // Let's check if the user provided valid credentials. Of course, you'd use a database or some third-party service // for this! // if (!(req.body.email === 'foo@bar.com' && req.body.password === 'foobar')) { // // Looks like the user provided invalid credentials, let's show the ui again... // res.render('login', { // csrfToken: req.csrfToken(), // challenge: challenge, // error: 'The username / password combination is not correct' // }); // return; // } // Seems like the user authenticated! Let's tell hydra... // hydra.acceptLoginRequest(challenge, { // // Subject is an alias for user ID. A subject can be a random string, a UUID, an email address, .... // subject: 'foo@bar.com', // // This tells hydra to remember the browser and automatically authenticate the user in future requests. This will // // set the "skip" parameter in the other route to true on subsequent requests! // remember: Boolean(req.body.remember), // // When the session expires, in seconds. Set this to 0 so it will never expire. // remember_for: 3600, // // Sets which "level" (e.g. 2-factor authentication) of authentication the user has. The value is really arbitrary // // and optional. In the context of OpenID Connect, a value of 0 indicates the lowest authorization level. // // acr: '0', // }) // .then(function (response) { // // All we need to do now is to redirect the user back to hydra! // res.redirect(response.redirect_to); // }) // // This will handle any error that happens when making HTTP calls to hydra // .catch(function (error) { // next(error); // }); // You could also deny the login request which tells hydra that no one authenticated! // hydra.rejectLoginRequest(challenge, { // error: 'invalid_request', // error_description: 'The user did something stupid...' // }) // .then(function (response) { // // All we need to do now is to redirect the browser back to hydra! // res.redirect(response.redirect_to); // }) // // This will handle any error that happens when making HTTP calls to hydra // .catch(function (error) { // next(error); // }); }); https://t.tt:9010 When login id/pwd, can use adminer change database user email/password. ...

2019-07-23 · 5 min · 927 words · Me

OpenID hydra docker-compose

docker-compose version: '3.3' services: ory-hydra-postgres: image: postgres:9.6 #restart: always environment: - POSTGRES_USER=hydra - POSTGRES_PASSWORD=secret - POSTGRES_DB=hydra volumes: - hydradata:/var/lib/postgresql/data:rw networks: - openid # 第一次執行postgres要做資料庫格式建立 PS: network依佈屬環境為主 docker network ls 確認 # docker run -it --rm \ # --network openid \ # oryd/hydra:latest \ # migrate sql --yes postgres://hydra:secret@ory-hydra-postgres:5432/hydra?sslmode=disable ory-hydra: image: oryd/hydra:latest restart: unless-stopped ports: - "9001:4444" - "9002:4445" environment: - SECRETS_SYSTEM=this_needs_to_be_the_same_a - DSN=postgres://hydra:secret@ory-hydra-postgres:5432/hydra?sslmode=disable - URLS_SELF_ISSUER=https://openid.hydra:9001/ - URLS_CONSENT=http://192.168.99.100:9020/consent - URLS_LOGIN=http://192.168.99.100:9020/login - LOG_LEVEL=debug - OAUTH2_EXPOSE_INTERNAL_ERRORS=true - SERVE_PUBLIC_CORS_ENABLED=true - SERVE_PUBLIC_CORS_ALLOWED_METHODS=POST,GET,PUT,DELETE - SERVE_ADMIN_CORS_ENABLED=true - SERVE_ADMIN_CORS_ALLOWED_METHODS=POST,GET,PUT,DELETE - SERVE_TLS_KEY_BASE64=LS0tLS1CRUdJTiBFQyBQQVJBTUVURVJTLS0tLS0KQmdVcmdRUUFJZz09Ci0tLS0tRU5EIEVDIFBBUkFNRVRFUlMtLS0tLQotLS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS0KTUlHa0FnRUJCRENLbkdnVnFJVzdZaW5iUWV5UEd5UTQ0R3U2VVFEelU5SENLYjMzTWlmeFJYRTBkbnU2KzdadQowdEJUcUhQRHVMeWdCd1lGSzRFRUFDS2haQU5pQUFSbng1Nk9jeGNyRWRsYmU4TXRSdUVxWGV2OEREcmh6ZWJGCjM4NlI4Q2RQWDRlUWI2Zll6ekFUL3V3STBsTDdvRmlEWEM3Q0JLWmZUcTdFSzN4TzNXWlpSSjJrMEQ3TnNLd2cKVEpZenJxT0JpczBNeGtva2FUWVVyemhKMXBKY3lmWT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo= - SERVE_TLS_CERT_BASE64=LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNQVENDQWNLZ0F3SUJBZ0lKQU13RjRiVDRvSnh0TUFvR0NDcUdTTTQ5QkFNQ01Gd3hDekFKQmdOVkJBWVQKQWtGVk1STXdFUVlEVlFRSURBcFRiMjFsTFZOMFlYUmxNU0V3SHdZRFZRUUtEQmhKYm5SbGNtNWxkQ0JYYVdSbgphWFJ6SUZCMGVTQk1kR1F4RlRBVEJnTlZCQU1NREc5d1pXNXBaQzVvZVdSeVlUQWVGdzB4T1RBMk1UY3dNVEl4Ck16ZGFGdzB5T1RBMk1UUXdNVEl4TXpkYU1Gd3hDekFKQmdOVkJBWVRBa0ZWTVJNd0VRWURWUVFJREFwVGIyMWwKTFZOMFlYUmxNU0V3SHdZRFZRUUtEQmhKYm5SbGNtNWxkQ0JYYVdSbmFYUnpJRkIwZVNCTWRHUXhGVEFUQmdOVgpCQU1NREc5d1pXNXBaQzVvZVdSeVlUQjJNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWlBMklBQkdmSG5vNXpGeXNSCjJWdDd3eTFHNFNwZDYvd01PdUhONXNYZnpwSHdKMDlmaDVCdnA5alBNQlArN0FqU1V2dWdXSU5jTHNJRXBsOU8KcnNRcmZFN2RabGxFbmFUUVBzMndyQ0JNbGpPdW80R0t6UXpHU2lScE5oU3ZPRW5Xa2x6SjlxTlFNRTR3SFFZRApWUjBPQkJZRUZHK3Z6ZkIxYmVnM1VadEpYRXZWOWRNa1hvNmdNQjhHQTFVZEl3UVlNQmFBRkcrdnpmQjFiZWczClVadEpYRXZWOWRNa1hvNmdNQXdHQTFVZEV3UUZNQU1CQWY4d0NnWUlLb1pJemowRUF3SURhUUF3WmdJeEFMUHYKODZFSFRUVElLcEJHdlQrY2NWN3djSC84SFIrc2xhZC9ZUFhLUlZwd2RDbzUyZVRPV3BDS2dGamtHNEJhd1FJeApBTGxGZFgwbEk2ZzhXS3lhRTVmKzJGZEkxYWVqQ0Ftd0xPTTZTRFJhNFVHbitDa2VwOEljeG1CTDIvQmUzSVZ6CjhnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo= networks: - openid #這行非常重要,docker成功運行後,要進geht console執行 admin.addPeer("enode://444a16729d32431bbdaa594272e3509cdeaaf3c995ffb583589163d35f8b36ad14394ab037ac186525f579700e6500cacfb1f953fdf066fa05da0e1d409f7f79@140.110.18.199:30301") ory-hydra-login-consent: #image: oryd/hydra-login-consent-node:latest build: context: hydra-login-consent-node/ restart: unless-stopped ports: - "9020:3000" environment: - HYDRA_ADMIN_URL=https://ory-hydra:4445 - NODE_TLS_REJECT_UNAUTHORIZED=0 volumes: - hydraloginconsent:/usr/src/app:rw networks: - openid # 快速建立 auth-doce-client PS: network依佈屬環境為主 docker network ls 確認 #docker run --rm -it \ # -e HYDRA_ADMIN_URL=https://ory-hydra:4445 \ # --network openid \ # oryd/hydra:latest \ # clients create --skip-tls-verify \ # --id auth-code-client \ # --secret secret \ # --grant-types authorization_code,refresh_token \ # --response-types code,id_token,token \ # --scope openid,offline,photos.read \ # --callbacks https://t.tt:9010/callback volumes: hydradata: hydraloginconsent: networks: openid: driver: bridge ory-hydra-login-consent download https://github.com/ory/hydra-login-consent-node Directory name is hydra-login-consent-node ...

2019-07-23 · 1 min · 186 words · Me