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'
|
||||
|
||||
# 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:
|
||||
# Service redis pour le stockage des sessions
|
||||
redis:
|
||||
image: redis:4.0
|
||||
container_name: redis
|
||||
|
@ -11,25 +25,22 @@ services:
|
|||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
|
||||
postgres:
|
||||
image: postgres:${POSTGRES_VERSION:-13}-alpine
|
||||
container_name: postgres
|
||||
# Service postgresql pour le stockage de la bdd applicative
|
||||
postgresql:
|
||||
image: postgres:13-alpine
|
||||
container_name: postgresql
|
||||
hostname: postgresql
|
||||
environment:
|
||||
POSTGRES_DB: ${POSTGRES_DB:-app}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-ChangeMe}
|
||||
POSTGRES_USER: ${POSTGRES_USER:-symfony}
|
||||
POSTGRES_MULTIPLE_DATABASES: app,hydra
|
||||
POSTGRES_PASSWORD: ChangeMe
|
||||
POSTGRES_USER: symfony
|
||||
ports:
|
||||
- 5432:5432
|
||||
volumes:
|
||||
- db-data:/var/lib/postgresql/data:rw
|
||||
- ./containers/postgresql:/docker-entrypoint-initdb.d
|
||||
|
||||
mailer:
|
||||
image: schickling/mailcatcher
|
||||
container_name: mailer
|
||||
ports:
|
||||
- 1025:1025
|
||||
- 1080:1080
|
||||
|
||||
# Service websocket
|
||||
mercure:
|
||||
image: dunglas/mercure
|
||||
container_name: mercure
|
||||
|
@ -48,38 +59,7 @@ services:
|
|||
- mercure_data:/data
|
||||
- mercure_config:/config
|
||||
|
||||
openldap:
|
||||
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
|
||||
|
||||
# Service de stockage Minio
|
||||
minio1:
|
||||
image: minio/minio:RELEASE.2021-01-16T02-19-44Z
|
||||
container_name: minio1
|
||||
|
@ -98,6 +78,7 @@ services:
|
|||
timeout: 20s
|
||||
retries: 3
|
||||
|
||||
# Service de stockage Minio
|
||||
minio2:
|
||||
image: minio/minio:RELEASE.2021-01-16T02-19-44Z
|
||||
container_name: minio2
|
||||
|
@ -116,6 +97,7 @@ services:
|
|||
timeout: 20s
|
||||
retries: 3
|
||||
|
||||
# Service de stockage Minio
|
||||
minio3:
|
||||
image: minio/minio:RELEASE.2021-01-16T02-19-44Z
|
||||
container_name: minio3
|
||||
|
@ -134,6 +116,7 @@ services:
|
|||
timeout: 20s
|
||||
retries: 3
|
||||
|
||||
# Service de stockage Minio
|
||||
minio4:
|
||||
image: minio/minio:RELEASE.2021-01-16T02-19-44Z
|
||||
container_name: minio4
|
||||
|
@ -152,6 +135,7 @@ services:
|
|||
timeout: 20s
|
||||
retries: 3
|
||||
|
||||
# Service nginx orchestrateur des minio
|
||||
nginx:
|
||||
image: nginx:1.19.2-alpine
|
||||
container_name: nginx
|
||||
|
@ -165,6 +149,120 @@ services:
|
|||
- minio3
|
||||
- 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:
|
||||
db-data:
|
||||
mercure_data:
|
||||
|
|
|
@ -214,8 +214,10 @@ class SecurityController extends AbstractController
|
|||
|
||||
public function loginOPENID(Request $request, AuthenticationUtils $authenticationUtils)
|
||||
{
|
||||
$state=Uuid::uuid4();
|
||||
$request->getSession()->set("oauthState",$state);
|
||||
$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);
|
||||
}
|
||||
|
||||
|
@ -236,15 +238,20 @@ class SecurityController extends AbstractController
|
|||
"client_id" => $this->getParameter("oauthClientid"),
|
||||
"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);
|
||||
$token=$response->body->access_token;
|
||||
$request->getSession()->set("oauthToken",$token);
|
||||
if(!$response||$response->code!="200") die("pb openid 01");
|
||||
$accesstoken=$response->body->access_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");
|
||||
$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);
|
||||
|
||||
|
@ -346,14 +353,21 @@ class SecurityController extends AbstractController
|
|||
|
||||
|
||||
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);
|
||||
$request->getSession()->invalidate();
|
||||
|
||||
$url=$this->getParameter("oauthLogouturl");
|
||||
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);
|
||||
|
||||
} else return $this->redirect($this->generateUrl("app_home"));
|
||||
}
|
||||
|
||||
|
|
|
@ -19,12 +19,25 @@ class ApiService
|
|||
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
|
||||
switch($content) {
|
||||
case "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);
|
||||
else $header=$headerini;
|
||||
|
@ -42,9 +55,6 @@ class ApiService
|
|||
\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;
|
||||
switch($method) {
|
||||
case "POST":
|
||||
|
|
Loading…
Reference in New Issue