froxlor / Froxlor

The server administration software for your needs - The official Froxlor development Git repository
http://www.froxlor.org
GNU General Public License v2.0
1.64k stars 458 forks source link

[FR] SAMl/OIDC(-supported) Authentication #973

Open patschi opened 3 years ago

patschi commented 3 years ago

Is your feature request related to a problem? Please describe. No.

Describe the solution you'd like I'd appreciate a "SAML/OIDC-supported authentication" when e.g. a Load Balancer/reverse proxy is doing the SAML challenge in front of the Froxlor instance.

In this case it works like:

  1. You visit froxlor.domain.tld
  2. LB/RP redirects to the SAML IDP, does its magic
  3. On success auth, it redirects through to Froxlor

With a bit support of Froxlor it would continue with:

  1. A specific HTTP header is added from the LB/RP facing towards Froxlor (e.g. X-User-Authed: user1)
  2. Froxlor checks for existence of header X-User-Authed: user1
  3. If so, parsing the username and initiating logon without password authentication

This would allow an integration with https://github.com/authelia/authelia or other LBs doing such authentication (proprietary Avi Load Balancer in my case)

(In a perfect world, a standalone authentication to Froxlor via SAML/OIDC would be great)

Describe alternatives you've considered None.

Additional context None.

patschi commented 3 years ago

A very, very rudimentary hack in index.php I experimented with was:

index.php:

105a106,112
>
>       $samlAuth = false;
>       if (isset($_SERVER['HTTP_X_SAML_USER']) && !empty($_SERVER['HTTP_X_SAML_USER'])) {
>               $samlAuth = true;
>               $_POST['send'] = 'send';
>       }
>
109a117,121
>               if ($samlAuth) {
>                       $loginname = $_SERVER['HTTP_X_SAML_USER'];
>                       $password = '';
>               }
>
214c226
<               } elseif (\Froxlor\System\Crypt::validatePasswordLogin($userinfo, $password, $table, $uid)) {
---
>               } elseif ($samlAuth === true || \Froxlor\System\Crypt::validatePasswordLogin($userinfo, $password, $table, $uid)) {

However not perfect, as this results in errors when the SAML user wasn't previously created in the Froxlor database...

d00p commented 3 years ago

so, I can fake the HTTP_X_SAML_USER, set it to admin and I'm logged in without any further check? I don't really think this is how this should work....there must be some challenge-hash or similar which is validated from the other side...Never worked woth SAML or similar though, maybe i'm totally misunderstanding

d00p commented 3 years ago

From what I read/see here, this is way more complex: https://github.com/onelogin/php-saml

patschi commented 3 years ago

Depends on the implementation. Of course you can either 1) integrate SAML completely using onelogin's SAML library and do the SAML authentication directly, 2) or, what I've decided to, go the easier route which requires less changes to Froxlor itself by letting the authentication up to the reverse proxy.

As described in my first post, there are reverse proxies (authelia)/load balancer (e.g. Avi Load Balancer) which can do the SAML authentication independently before access to the real application is granted. When the authentication succeeds, you can add a HTTP header (with any name, example with Authelia & Jira) with the username, which the real application (in this case Froxlor) can read and work with.

My cheap implementation just has one issue: When the username doesn't exist in the Froxlor account, a PHP error is thrown. So it's really just quick'n'dirty.

I hope this makes sense!