mod_rewrite and auth in Apaches Location-Directive

59 views
Skip to first unread message

Red Nose

unread,
Apr 25, 2017, 9:10:57 AM4/25/17
to Fat-Free Framework
Hi,

to make it clear: This is, as far as i know, not a f3-specific question but maybe you can give me a few hints how to solve this.

I'm creating a Site with f3 and want to protected some routes by Kerberos for Authentication and LDAP(MS AD) for Authorization.
I know that Apache is able to handle both so i thought i can do this Auth*-stuff completly in Apache and keep f3 free from it.
So a User should first be authenticated via Kerberos and then the System should check if the User is in a given group.

My Apache-conf looks like this (simplified):
<VirtualHost *:80>
   ServerName server.example.com
   DocumentRoot /var/www/html/project/public

   <Directory /var/www/html/project/public>
      Options -Indexes +FollowSymLinks +Includes
      AllowOverride All
      require all granted
   </Directory>

   <Location /index.php>
      AuthName "Restricted Access"
      AuthType Kerberos
      Krb5Keytab /etc/krb5.keytab
      KrbAuthRealms EXAMPLE.COM
      KrbServiceName HTTP

      AuthLDAPURL "ldap://xxx.xxx.xxx.xxx:3268/DC=example,DC=com?userPrincipalName"
      AuthLDAPBindDN "user...@example.com"
      AuthLDAPBindPassword "password"
      AuthLDAPSubGroupClass group
      require ldap-group CN=Users,DC=example,DC=com
   </Location>
</VirtualHost>


The .htaccess is the default one
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule .* index.php [L,QSA]

This all works as far as i use it at the moment, but i'm not able to check for any f3-route (for example <Location /secure> does not work).
As far as i understand, mod_rewrite happens before Apache checks for the Location and thats why i can't use it.
So it's a all-or-nothing solution and i can't make parts of f3 public available or the other way, secure only some routes of f3.

The only solution i came up to is to move the Authorization into f3. Or am i missing something here and there is a more elegant solution for this?

Anatol

unread,
Apr 26, 2017, 1:58:23 PM4/26/17
to Fat-Free Framework
Unfortunately I do not know about kerberos config but
have you tried to move the .htaccess config in your vhost config?
As far as I know the .htaccess comes last and overwrites in every
case conf files are parsed from top to bottom.

by the way there exists an fantastic access plugin for f3 written bei xfra 
if you decide to move stuff to f3: https://github.com/xfra35/f3-access

Red Nose

unread,
Apr 27, 2017, 8:52:09 AM4/27/17
to Fat-Free Framework
I'm not sure what you mean by 'move the .htaccess config'.
I tried to put the Directory-Directive on the end of the vhost-config, but that didn't change anything.

I tried 'LogLevel debug rewrite:trace3' and saw that mod_rewrite happens first...
So a call to http://example.com/secure is internally redirected to http://example.com/index.php.
Thats why a <Location /secure></Location> is not working at all.

But thanks for the f3-access tip! I'll have a look at this plugin as i see no other solution to this.
F3 is really great stuff and i'm loving all the flexibility!

ved

unread,
Apr 27, 2017, 9:43:50 AM4/27/17
to Fat-Free Framework
I've personally never connected a webapp to AD but here's some info and links that may or may not help.

F3's auth class seems to support LDAP but it doesn't seem to be very well documented or have that use case on the test branch so I'm not really sure if that can maybe help on the auth part.

You can also probably write your own auth and authorization class using php's own ldap functions or see if any of these composer packages can help you.

Red Nose

unread,
Apr 28, 2017, 3:41:31 AM4/28/17
to Fat-Free Framework
Thanks for all the helpful tips.

In the end i moved the Authorization-Part into F3 using plain ldap and the ->beforeRoute() Function.
Authentication is still done by apache+mod_kerberos and is working pretty nice.

This is basically how to check if a given AD-User (UserPrincipalName) is part of one or more AD-Groups (distinguishedName):

    public function isUPNUserInGroup($upn, array $groups)
    {
        $filter = "(&"
                . "(userPrincipalName=".ldap_escape($upn).")"
                . "(|";
       
        foreach ($groups as $group) {
            // search recursive through all subgroups (AD-specific)
            $filter .= "(memberOf:1.2.840.113556.1.4.1941:=".ldap_escape($group).")";            
        }
       
        $filter .= "))";

        // $this->ldap = LDAP resource
        // $this->base = LDAP BaseDN
        $result = ldap_search($this->ldap, $this->base, $filter);
       
        $data = ldap_get_entries($this->ldap, $result);
       
        if ($data['count'] > 0) {
                return true;
        }

        return false;

    }
Reply all
Reply to author
Forward
0 new messages