hydra passwordless
This commit is contained in:
parent
7962e2ca9a
commit
21fb28a6f0
|
@ -0,0 +1,5 @@
|
||||||
|
FROM cadoles/hydra-dispatcher-v1:v0.0.0-111-g2e60bdb
|
||||||
|
|
||||||
|
COPY hydra/providers.yml /var/www/config/hydra/providers.yml
|
||||||
|
|
||||||
|
COPY theme.css /var/www/public/build/theme
|
|
@ -0,0 +1,23 @@
|
||||||
|
hydra:
|
||||||
|
apps:
|
||||||
|
- id: passwordless
|
||||||
|
title:
|
||||||
|
fr: addresse courriel
|
||||||
|
en: email address
|
||||||
|
description:
|
||||||
|
fr: Authentification via adresse courriel
|
||||||
|
en: Authentication by email address
|
||||||
|
icon_url: https://upload.wikimedia.org/wikipedia/commons/4/48/You%27ve_got_mail.png
|
||||||
|
login_url: http://127.0.0.1:7082/login
|
||||||
|
consent_url: http://127.0.0.1:7082/consent
|
||||||
|
logout_url: http://127.0.0.1:7082/logout
|
||||||
|
attributes_rewrite_rules:
|
||||||
|
username:
|
||||||
|
- consent.session.id_token.email
|
||||||
|
email:
|
||||||
|
- consent.session.id_token.email
|
||||||
|
email_verified:
|
||||||
|
- consent.session.id_token.email_verified
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
body > section {
|
||||||
|
background-color: rgba(214, 170, 214, 0.575);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="radio"]:checked ~ .app-item {
|
||||||
|
--tw-shadow: 0 10px 15px -3px rgb(22 78 99 / 0.3), 0 4px 6px -4px rgb(22 78 99 / 0.3);
|
||||||
|
background-color: rgba(251, 255, 21, 0.507);
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"client_id": "nineskeletor",
|
||||||
|
"client_name": "Nineskeletor",
|
||||||
|
"client_secret": "changeme",
|
||||||
|
"grant_types": [
|
||||||
|
"authorization_code",
|
||||||
|
"refresh_token"
|
||||||
|
],
|
||||||
|
"jwks": {},
|
||||||
|
"metadata": {},
|
||||||
|
"token_endpoint_auth_method": "client_secret_post",
|
||||||
|
"post_logout_redirect_uris": ["https://127.0.0.1:8000"],
|
||||||
|
"redirect_uris": ["https://127.0.0.1:8000/oauth2/callback"],
|
||||||
|
"response_types": [
|
||||||
|
"code"
|
||||||
|
],
|
||||||
|
"logo_uri": "https://upload.wikimedia.org/wikipedia/commons/e/e1/Password.svg",
|
||||||
|
"scope": "openid"
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -u
|
||||||
|
|
||||||
|
function create_user_and_database() {
|
||||||
|
local database=$1
|
||||||
|
echo " Creating user and database '$database'"
|
||||||
|
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
|
||||||
|
CREATE USER $database;
|
||||||
|
CREATE DATABASE $database;
|
||||||
|
GRANT ALL PRIVILEGES ON DATABASE $database TO $database;
|
||||||
|
EOSQL
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then
|
||||||
|
echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES"
|
||||||
|
for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do
|
||||||
|
create_user_and_database $db
|
||||||
|
done
|
||||||
|
echo "Multiple databases created"
|
||||||
|
fi
|
|
@ -1,6 +1,20 @@
|
||||||
version: '3'
|
version: '3'
|
||||||
|
|
||||||
|
# Port
|
||||||
|
# 6379 = redis
|
||||||
|
# 5432 = postgresql
|
||||||
|
# 80 = mercure
|
||||||
|
# 9000 = minio nginx
|
||||||
|
# 1025 = fake smtp
|
||||||
|
# 1080 = fake webmail
|
||||||
|
# 389 = fake ldap
|
||||||
|
# 636 = fake ldaps
|
||||||
|
# 6080 = tool phpldapadmin
|
||||||
|
# 6081 = tool adminer
|
||||||
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
# Service redis pour le stockage des sessions
|
||||||
redis:
|
redis:
|
||||||
image: redis:4.0
|
image: redis:4.0
|
||||||
container_name: redis
|
container_name: redis
|
||||||
|
@ -11,25 +25,22 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
|
||||||
postgres:
|
# Service postgresql pour le stockage de la bdd applicative
|
||||||
image: postgres:${POSTGRES_VERSION:-13}-alpine
|
postgresql:
|
||||||
container_name: postgres
|
image: postgres:13-alpine
|
||||||
|
container_name: postgresql
|
||||||
|
hostname: postgresql
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: ${POSTGRES_DB:-app}
|
POSTGRES_MULTIPLE_DATABASES: app,hydra
|
||||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-ChangeMe}
|
POSTGRES_PASSWORD: ChangeMe
|
||||||
POSTGRES_USER: ${POSTGRES_USER:-symfony}
|
POSTGRES_USER: symfony
|
||||||
ports:
|
ports:
|
||||||
- 5432:5432
|
- 5432:5432
|
||||||
volumes:
|
volumes:
|
||||||
- db-data:/var/lib/postgresql/data:rw
|
- db-data:/var/lib/postgresql/data:rw
|
||||||
|
- ./containers/postgresql:/docker-entrypoint-initdb.d
|
||||||
|
|
||||||
mailer:
|
# Service websocket
|
||||||
image: schickling/mailcatcher
|
|
||||||
container_name: mailer
|
|
||||||
ports:
|
|
||||||
- 1025:1025
|
|
||||||
- 1080:1080
|
|
||||||
|
|
||||||
mercure:
|
mercure:
|
||||||
image: dunglas/mercure
|
image: dunglas/mercure
|
||||||
container_name: mercure
|
container_name: mercure
|
||||||
|
@ -48,38 +59,7 @@ services:
|
||||||
- mercure_data:/data
|
- mercure_data:/data
|
||||||
- mercure_config:/config
|
- mercure_config:/config
|
||||||
|
|
||||||
openldap:
|
# Service de stockage Minio
|
||||||
image: osixia/openldap:1.5.0
|
|
||||||
container_name: openldap
|
|
||||||
environment:
|
|
||||||
LDAP_LOG_LEVEL: "256"
|
|
||||||
LDAP_ORGANISATION: "nineskeletor"
|
|
||||||
LDAP_DOMAIN: "nine.fr"
|
|
||||||
LDAP_ADMIN_PASSWORD: "changeme"
|
|
||||||
LDAP_CONFIG_PASSWORD: "changeme"
|
|
||||||
LDAP_READONLY_USER: "true"
|
|
||||||
LDAP_READONLY_USER_USERNAME: "readonly"
|
|
||||||
LDAP_READONLY_USER_PASSWORD: "readonly"
|
|
||||||
LDAP_TLS: "false"
|
|
||||||
volumes:
|
|
||||||
- /var/lib/ldap
|
|
||||||
- /etc/ldap/slapd.d
|
|
||||||
- /container/service/slapd/assets/certs/
|
|
||||||
ports:
|
|
||||||
- "389:389"
|
|
||||||
- "636:636"
|
|
||||||
|
|
||||||
phpldapadmin:
|
|
||||||
image: osixia/phpldapadmin:latest
|
|
||||||
container_name: phpldapadmin
|
|
||||||
environment:
|
|
||||||
PHPLDAPADMIN_LDAP_HOSTS: "openldap"
|
|
||||||
PHPLDAPADMIN_HTTPS: "false"
|
|
||||||
ports:
|
|
||||||
- "8080:80"
|
|
||||||
depends_on:
|
|
||||||
- openldap
|
|
||||||
|
|
||||||
minio1:
|
minio1:
|
||||||
image: minio/minio:RELEASE.2021-01-16T02-19-44Z
|
image: minio/minio:RELEASE.2021-01-16T02-19-44Z
|
||||||
container_name: minio1
|
container_name: minio1
|
||||||
|
@ -98,6 +78,7 @@ services:
|
||||||
timeout: 20s
|
timeout: 20s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|
||||||
|
# Service de stockage Minio
|
||||||
minio2:
|
minio2:
|
||||||
image: minio/minio:RELEASE.2021-01-16T02-19-44Z
|
image: minio/minio:RELEASE.2021-01-16T02-19-44Z
|
||||||
container_name: minio2
|
container_name: minio2
|
||||||
|
@ -116,6 +97,7 @@ services:
|
||||||
timeout: 20s
|
timeout: 20s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|
||||||
|
# Service de stockage Minio
|
||||||
minio3:
|
minio3:
|
||||||
image: minio/minio:RELEASE.2021-01-16T02-19-44Z
|
image: minio/minio:RELEASE.2021-01-16T02-19-44Z
|
||||||
container_name: minio3
|
container_name: minio3
|
||||||
|
@ -134,6 +116,7 @@ services:
|
||||||
timeout: 20s
|
timeout: 20s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|
||||||
|
# Service de stockage Minio
|
||||||
minio4:
|
minio4:
|
||||||
image: minio/minio:RELEASE.2021-01-16T02-19-44Z
|
image: minio/minio:RELEASE.2021-01-16T02-19-44Z
|
||||||
container_name: minio4
|
container_name: minio4
|
||||||
|
@ -152,6 +135,7 @@ services:
|
||||||
timeout: 20s
|
timeout: 20s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|
||||||
|
# Service nginx orchestrateur des minio
|
||||||
nginx:
|
nginx:
|
||||||
image: nginx:1.19.2-alpine
|
image: nginx:1.19.2-alpine
|
||||||
container_name: nginx
|
container_name: nginx
|
||||||
|
@ -165,6 +149,120 @@ services:
|
||||||
- minio3
|
- minio3
|
||||||
- minio4
|
- minio4
|
||||||
|
|
||||||
|
# Service hydra
|
||||||
|
hydra:
|
||||||
|
image: cadoles/hydra-v1
|
||||||
|
container_name: hydra
|
||||||
|
volumes:
|
||||||
|
- ./containers/hydra/clients.d:/etc/hydra/clients.d
|
||||||
|
ports:
|
||||||
|
- 7080:4444
|
||||||
|
links:
|
||||||
|
- postgresql
|
||||||
|
depends_on:
|
||||||
|
- postgresql
|
||||||
|
restart: on-failure
|
||||||
|
environment:
|
||||||
|
LOG_LEAK_SENSITIVE_VALUES: "true"
|
||||||
|
HYDRA_URLS_SELF_ISSUER: http://127.0.0.1:7080
|
||||||
|
HYDRA_URLS_CONSENT: http://127.0.0.1:7081/consent
|
||||||
|
HYDRA_URLS_LOGIN: http://127.0.0.1:7081/login
|
||||||
|
HYDRA_URLS_LOGOUT: http://127.0.0.1:7081/logout
|
||||||
|
HYDRA_DSN: postgres://symfony:ChangeMe@postgresql:5432/hydra
|
||||||
|
#HYDRA_WAIT4X_DATABASE_TYPE: postgres
|
||||||
|
#HYDRA_WAIT4X_DATABASE_DSN: postgres://symfony:ChangeMe@postgresql:5432/hydra
|
||||||
|
HYDRA_ALLOW_INSECURE: "yes"
|
||||||
|
HYDRA_LEVEL: debug
|
||||||
|
|
||||||
|
hydra-dispatcher:
|
||||||
|
build:
|
||||||
|
context: ./containers/hydra-dispatcher
|
||||||
|
container_name: hydra-dispatcher
|
||||||
|
links:
|
||||||
|
- hydra
|
||||||
|
ports:
|
||||||
|
- 7081:80
|
||||||
|
restart: on-failure
|
||||||
|
environment:
|
||||||
|
- APP_ENV=dev
|
||||||
|
- APP_DEBUG=yes
|
||||||
|
- HYDRA_BASE_URL=http://hydra:4444
|
||||||
|
- HYDRA_ADMIN_BASE_URL=http://hydra:4445
|
||||||
|
# url dispatcher
|
||||||
|
- BASE_URL=http://127.0.0.1:7081
|
||||||
|
- COOKIE_PATH=/
|
||||||
|
- DEFAULT_LOCALE=fr
|
||||||
|
- APP_LOCALES=fr,en
|
||||||
|
volumes:
|
||||||
|
- ./containers/hydra-dispatcher/hydra:/var/www/config/hydra:ro
|
||||||
|
|
||||||
|
hydra-passwordless:
|
||||||
|
image: cadoles/hydra-passwordless-v1
|
||||||
|
container_name: hydra-passwordless
|
||||||
|
environment:
|
||||||
|
- HTTP_BASE_URL=http://127.0.0.1:7082/
|
||||||
|
- SMTP_HOST=mailer
|
||||||
|
- SMTP_PORT=1025
|
||||||
|
- SMTP_SENDER_ADDRESS=noreply@hydra.local
|
||||||
|
- SMTP_SENDER_NAME="Authentification - Passwordless"
|
||||||
|
- HYDRA_BASE_URL=http://hydra-dispatcher
|
||||||
|
links:
|
||||||
|
- hydra
|
||||||
|
- hydra-dispatcher
|
||||||
|
- mailer
|
||||||
|
ports:
|
||||||
|
- 7082:3000
|
||||||
|
|
||||||
|
# Service fake smtp = optionnel
|
||||||
|
mailer:
|
||||||
|
image: schickling/mailcatcher
|
||||||
|
container_name: mailer
|
||||||
|
ports:
|
||||||
|
- 1025:1025
|
||||||
|
- 1080:1080
|
||||||
|
|
||||||
|
# Service fake openldap = optionnel si nineskeletor a une synchronisation avec un annuaire
|
||||||
|
openldap:
|
||||||
|
image: osixia/openldap:1.5.0
|
||||||
|
container_name: openldap
|
||||||
|
environment:
|
||||||
|
LDAP_LOG_LEVEL: "256"
|
||||||
|
LDAP_ORGANISATION: "nine"
|
||||||
|
LDAP_DOMAIN: "nine.fr"
|
||||||
|
LDAP_ADMIN_PASSWORD: "changeme"
|
||||||
|
LDAP_CONFIG_PASSWORD: "changeme"
|
||||||
|
LDAP_READONLY_USER: "true"
|
||||||
|
LDAP_READONLY_USER_USERNAME: "readonly"
|
||||||
|
LDAP_READONLY_USER_PASSWORD: "readonly"
|
||||||
|
LDAP_TLS: "false"
|
||||||
|
volumes:
|
||||||
|
- /var/lib/ldap
|
||||||
|
- /etc/ldap/slapd.d
|
||||||
|
- /container/service/slapd/assets/certs/
|
||||||
|
ports:
|
||||||
|
- "389:389"
|
||||||
|
- "636:636"
|
||||||
|
|
||||||
|
# Service tool phpldapadmin = optionnel dans le cas de la présence d'un fake openldap
|
||||||
|
phpldapadmin:
|
||||||
|
image: osixia/phpldapadmin:latest
|
||||||
|
container_name: phpldapadmin
|
||||||
|
environment:
|
||||||
|
PHPLDAPADMIN_LDAP_HOSTS: "openldap"
|
||||||
|
PHPLDAPADMIN_HTTPS: "false"
|
||||||
|
ports:
|
||||||
|
- "6080:80"
|
||||||
|
depends_on:
|
||||||
|
- openldap
|
||||||
|
|
||||||
|
# Service tool adminer = optionnel
|
||||||
|
adminer:
|
||||||
|
image: adminer
|
||||||
|
container_name: adminer
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- 6081:8080
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
db-data:
|
db-data:
|
||||||
mercure_data:
|
mercure_data:
|
||||||
|
|
|
@ -214,8 +214,10 @@ class SecurityController extends AbstractController
|
||||||
|
|
||||||
public function loginOPENID(Request $request, AuthenticationUtils $authenticationUtils)
|
public function loginOPENID(Request $request, AuthenticationUtils $authenticationUtils)
|
||||||
{
|
{
|
||||||
|
$state=Uuid::uuid4();
|
||||||
|
$request->getSession()->set("oauthState",$state);
|
||||||
$callback=$this->generateUrl('app_loginopenidcallback', array(), UrlGeneratorInterface::ABSOLUTE_URL);
|
$callback=$this->generateUrl('app_loginopenidcallback', array(), UrlGeneratorInterface::ABSOLUTE_URL);
|
||||||
$url=$this->getParameter("oauthLoginurl")."?client_id=".$this->getParameter("oauthClientid")."&redirect_uri=".$callback."&response_type=code&state=12345678&scope=openid";
|
$url=$this->getParameter("oauthLoginurl")."?client_id=".$this->getParameter("oauthClientid")."&redirect_uri=".$callback."&response_type=code&state=".$state."&scope=openid";
|
||||||
return $this->redirect($url);
|
return $this->redirect($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,15 +238,20 @@ class SecurityController extends AbstractController
|
||||||
"client_id" => $this->getParameter("oauthClientid"),
|
"client_id" => $this->getParameter("oauthClientid"),
|
||||||
"client_secret" => $this->getParameter("oauthClientsecret"),
|
"client_secret" => $this->getParameter("oauthClientsecret"),
|
||||||
];
|
];
|
||||||
$response=$this->apiservice->run("POST",$apiurl,$query);
|
$response=$this->apiservice->run("POST",$apiurl,$query,null,"form");
|
||||||
|
|
||||||
if(!$response||$response->code!="200") return $this->logout($request);
|
if(!$response||$response->code!="200") die("pb openid 01");
|
||||||
$token=$response->body->access_token;
|
$accesstoken=$response->body->access_token;
|
||||||
$request->getSession()->set("oauthToken",$token);
|
$accesstokentype=$response->body->token_type;
|
||||||
|
$îdtoken=$response->body->id_token;
|
||||||
|
|
||||||
|
$request->getSession()->set("oauthAccesstoken",$accesstoken);
|
||||||
|
$request->getSession()->set("oauthIdtoken",$îdtoken);
|
||||||
|
|
||||||
$apiurl = $this->getParameter("oauthUserinfo");
|
$apiurl = $this->getParameter("oauthUserinfo");
|
||||||
$response=$this->apiservice->run("GET",$apiurl,null,["Authorization"=>"token ".$token]);
|
|
||||||
if(!$response||$response->code!="200") return $this->logout($request);
|
$response=$this->apiservice->run("GET",$apiurl,null,["Authorization"=>$accesstokentype." ".$accesstoken]);
|
||||||
|
if(!$response||$response->code!="200") die("pb openid 02");
|
||||||
|
|
||||||
$attributes=json_decode(json_encode($response->body), true);
|
$attributes=json_decode(json_encode($response->body), true);
|
||||||
|
|
||||||
|
@ -346,14 +353,21 @@ class SecurityController extends AbstractController
|
||||||
|
|
||||||
|
|
||||||
public function logoutOPENID(Request $request) {
|
public function logoutOPENID(Request $request) {
|
||||||
$token=$request->getSession()->get("oauthToken");
|
$accesstoken=$request->getSession()->get("oauthAccesstoken");
|
||||||
|
$idtoken=$request->getSession()->get("oauthIdtoken");
|
||||||
|
$state=$request->getSession()->get("oauthState");
|
||||||
|
|
||||||
$this->tokenstorage->setToken(null);
|
$this->tokenstorage->setToken(null);
|
||||||
$request->getSession()->invalidate();
|
$request->getSession()->invalidate();
|
||||||
|
|
||||||
$url=$this->getParameter("oauthLogouturl");
|
$url=$this->getParameter("oauthLogouturl");
|
||||||
if($url) {
|
if($url) {
|
||||||
$url.="?id_token_hint=$token&scope=openid&post_logout_redirect_uri=http://127.0.0.1:8000";
|
$callback=($request->isSecure()?"https://":"http://").str_replace("//","/",$this->getParameter("appWeburl").$this->getParameter("appAlias").$this->generateUrl('app_home'));
|
||||||
|
$callback=substr($callback, 0, -1);
|
||||||
|
|
||||||
|
$url.="?id_token_hint=$idtoken&scope=openid&state=$state&post_logout_redirect_uri=$callback";
|
||||||
return $this->redirect($url);
|
return $this->redirect($url);
|
||||||
|
|
||||||
} else return $this->redirect($this->generateUrl("app_home"));
|
} else return $this->redirect($this->generateUrl("app_home"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,25 @@ class ApiService
|
||||||
return \Unirest\Request\Body::json($array);
|
return \Unirest\Request\Body::json($array);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run($method,$url,$query,$header=null) {
|
public function run($method,$url,$query,$header=null,$content="json") {
|
||||||
// Entete
|
// Entete
|
||||||
$headerini = [
|
switch($content) {
|
||||||
'Accept' => 'application/json',
|
case "json":
|
||||||
'Content-Type' => 'application/json',
|
$headerini = [
|
||||||
];
|
'Accept' => 'application/json',
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
];
|
||||||
|
if($query) $query = \Unirest\Request\Body::json($query);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "form":
|
||||||
|
$headerini = [
|
||||||
|
'Accept' => 'application/json',
|
||||||
|
'Content-Type' => 'application/x-www-form-urlencoded',
|
||||||
|
];
|
||||||
|
if($query) $query = \Unirest\Request\Body::form($query);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if($header) $header=array_merge($headerini,$header);
|
if($header) $header=array_merge($headerini,$header);
|
||||||
else $header=$headerini;
|
else $header=$headerini;
|
||||||
|
@ -42,9 +55,6 @@ class ApiService
|
||||||
\Unirest\Request::proxy($proxyHost, $proxyPort, CURLPROXY_HTTP, true);
|
\Unirest\Request::proxy($proxyHost, $proxyPort, CURLPROXY_HTTP, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if($query) $query = \Unirest\Request\Body::json($query);
|
|
||||||
if($query) $query = http_build_query($query);
|
|
||||||
|
|
||||||
$response = false;
|
$response = false;
|
||||||
switch($method) {
|
switch($method) {
|
||||||
case "POST":
|
case "POST":
|
||||||
|
|
Loading…
Reference in New Issue