directus / v8-archive

Directus Database API — Wraps Custom SQL Databases with a REST/GraphQL API
https://docs.directus.io/api/reference.html
507 stars 203 forks source link

Add Custom Auth failing #2185

Open makuro opened 4 years ago

makuro commented 4 years ago

Bug Report

The custom oauth providers are not loaded after added to a custom dockerfile

Steps to Reproduce

  1. create a custom dockerfile like and add a custom oauth provider to it. The Folder "Files/Keycloak" is containing the auth.php, the icon.svg and the Provider.php needed.

FROM directus/directus:7.0.18

RUN mkdir -p /var/www/html/extensions/custom/auth/Keycloak COPY Files/Keycloak/ /var/www/html/exensions/custom/auth/Keycloak

  1. Run this docker image
  2. Try to connect from an directus:app image to the api
  3. The custom sso auth is not shown in the login screen, only the local login option

Expected Behavior

The icon.svg should be shown below the login form to access the custom login provider

Actual Behavior

the custom folder is completly ignored

Other Context & Screenshots

Technical Details

The main problem is, that when creating the docker container ( https://hub.docker.com/layers/directus/directus/7.0.18/images/sha256-0f03edd0ddf7f2a2a9dbf0dd34c59cb14988070323fb56fc4c9e0ea47cf3d88e )

the last command is: /bin/sh -c rm -rf /var/www/html/ && mv /var/www/public/ /var/www/html/

This contradicts the actual search for custom providers within the app https://github.com/directus/directus/blob/master/src/core/Directus/Application/CoreServicesProvider.php#L822 which explicitly accesses the public folder. To rename the public to html so that there won't be a problem with the apache seems to be the easy way here but kills the custom auth search as it can not find the custom providers

makuro commented 4 years ago

Next thing related would be, the https://github.com/directus/directus/blob/master/src/core/Directus/Application/CoreServicesProvider.php does not load the custom provider files correctly.

If inside the provider file, there is a custom oauth2 provider based on theleague oatuh2 then it can not be loaded as it does not fall anywhere inside the currently registered autoload folders and must be imported manually from the /public/ but maybe I should write another request for that

benhaynes commented 4 years ago

Hey @WoLfulus — is this a specific Docker issue? If so, we can transfer to that repo.

makuro commented 4 years ago

@benhaynes I would think so, as the normal installation guide tells to point the webdir to the /public folder and taking in credit that the currently latest dockerfile is 8 month old, there where some changes there.

makuro commented 4 years ago

@WoLfulus, @benhaynes Hi I did some digging around and get it working on my side, here are my findings:

so I updated my "custom" docker file to the following. I used the v2.6.0-apache as well as the latest and both got the same errors.

` FROM directus/api:latest

COPY Files/Context.php /var/www/src/core/Directus/Config/Context.php COPY Files/api.php /var/www/config/api.php COPY Files/Keycloak/ /var/www/public/extensions/custom/auth/Keycloak/ `

and tried to deploy that with DIRECTUS_USE_ENV=0 as I want the image to use the api.php and not the environment files. The Context.php is originated with changes from here: https://github.com/directus/api/issues/1337 but taken from the current image to fix the env var problem. within Keycloak is, like stated within the documentation, an svg file, the provider.php and the auth.php like stated here: https://docs.directus.io/extensions/auth-providers.html also the api.php contains under "auth"=> the settings for keycloak as under "custom" the mentioning of the custom adapter.

when accessing the sso endpoint on the api, all that returns is: {"data":[],"public":true}

So I started checking the endpoints and everything and I came to the CoreServicesProviders.php

there is the function getExternalAuth() inwhich there is a line

$providersConfig => $config->get('auth.social_providers', []);

no matter what I did to the api.php file, it never ever returned anything.

just for fun, here is my snippet from the api.php:

'auth' => [ 'secret_key' => '0GJzhyBOlo5VYSpi1Tn2ZRNsCQpjYkqa', 'public_key' => '3618222D-1561-4339-97fb-0d7a7c32aebf', 'social_providers' => [ 'Keycloak' => [ 'realm' => 'realmId', 'clientId' => 'clientID', 'clientSecret' => '', 'authServerUrl' => 'https://myauthserverurl, 'enabled' => true ] ] ],

yet, the array $providersconfig was empty no matter what I did. I do not have any caching enabled within the api.php, just as reference.

So I set the $providersConfig to above array containing my Keycloak.

Next thing I get is a couple lines below, that the class is not found.

Sure thing, because the class is expected under public/extensions/custom/auth yet there is no composer autoload path pointing in that direction.

So I added above the if (!class_exists($class)) { line the following snippet:

if (!class_exists($class) && $custom) { require_once('/var/www/public/extensions/custom/auth/'.$providerName.'/Provider.php'); }

to make it load the provider within the docker file.

Now I finally get my oauth2 to work, I see the icon appearing on the app and I can login, even tho I have to create a user with that email address from my oauth2 by hand within the system and the password is still saved as plain text, but that needs more sniffing around from my side and I will report this problem later on, maybe after the v8 is finally released and I did check there for errors in that constellation.

So, that is that.

TL;DR;

The paths are so far correct within the current :latest / :api.v2.6.0-apache image but the oauth2 is not loaded due to several other errors.