[open-ils-commits] [GIT] Evergreen ILS branch master updated. c542d830236a89ec3e20fcc89c5fc83a1608bfe5

Evergreen Git git at git.evergreen-ils.org
Fri Sep 6 17:43:35 EDT 2019


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".

The branch, master has been updated
       via  c542d830236a89ec3e20fcc89c5fc83a1608bfe5 (commit)
       via  ce22424c3156e5c53e79779008cc904ba26fd883 (commit)
       via  c485b3dcac422ad11e0cdb9d74f674e8c9f9355c (commit)
       via  3a7ca4a2c6c3d6ea893d13a38179e9b4a26e523a (commit)
      from  4d3fe7d66eb2c7ab50302f6f5feb5aa6d6853938 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit c542d830236a89ec3e20fcc89c5fc83a1608bfe5
Author: Jeff Davis <jdavis at sitka.bclibraries.ca>
Date:   Fri Jun 21 16:25:04 2019 -0700

    LP#1786552: AuthProxy: release note for LDAP bind_user and restrict_by_home_ou
    
    Signed-off-by: Jeff Davis <jdavis at sitka.bclibraries.ca>
    Signed-off-by: Galen Charlton <gmc at equinoxinitiative.org>

diff --git a/docs/RELEASE_NOTES_NEXT/Administration/ldap_bind_user.adoc b/docs/RELEASE_NOTES_NEXT/Administration/ldap_bind_user.adoc
new file mode 100644
index 0000000000..20f7f82e47
--- /dev/null
+++ b/docs/RELEASE_NOTES_NEXT/Administration/ldap_bind_user.adoc
@@ -0,0 +1,34 @@
+AuthProxy Support for Arbitrary LDAP Usernames
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+AuthProxy now supports LDAP-based login with a username that is
+different from your Evergreen username.
+
+This feature may be useful for libraries that use an LDAP server for
+single sign-on (SSO).  Let's say you are a post-secondary library using
+student or employee numbers as Evergreen usernames, but you want people
+to be able to login to Evergreen with their SSO credentials, which may
+be different from their student/employee number.  To support this,
+AuthProxy can now be configured to accept your SSO username on login,
+use it to look up your student/employee number on the LDAP server, and
+log you in as the appropriate Evergreen user.
+
+For this to work, in the AuthProxy configuration for your LDAP server in
+opensrf.xml, set "bind_attr" to the LDAP field containing your LDAP
+username, and "id_attr" to the LDAP field containing your student or
+employee number (or whatever other value is used as your Evergreen
+username).  If "bind_attr" is not set, Evergreen will assume that your
+LDAP username and Evergreen username are the same.
+
+Now, let's say your LDAP server is only an authoritative auth provider
+for Library A.  Nothing prevents the server from reporting that your
+student number is 000000, even if that Evergreen username is already in
+use by another patron at Library B.  We want to ensure that AuthProxy
+does not use Library A's LDAP server to log you in as the Library B
+patron.  For this reason, a new "restrict_by_home_ou" setting has been
+added to AuthProxy config.  When enabled, this setting restricts LDAP
+authentication to users belonging to a library served by that LDAP
+server (i.e. the user's home library must match the LDAP server's
+"org_units" setting in opensrf.xml).  Use of this setting is strongly
+recommended.
+

commit ce22424c3156e5c53e79779008cc904ba26fd883
Author: Jeff Davis <jdavis at sitka.bclibraries.ca>
Date:   Thu Jun 20 12:49:31 2019 -0700

    LP#1786552: AuthProxy: restrict_by_home_ou based on authenticator org_units
    
    It makes more sense to check the patron's home library against the org
    units to which the authenticator applies, rather than the login org
    param.
    
    Signed-off-by: Jeff Davis <jdavis at sitka.bclibraries.ca>
    Signed-off-by: Galen Charlton <gmc at equinoxinitiative.org>

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy.pm
index d0fcbe7881..dbf4db474c 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy.pm
@@ -261,11 +261,26 @@ sub login {
                     return OpenILS::Event->new( 'LOGIN_FAILED' );
                 } else {
                     my $restrict_by_ou = $authenticator->{restrict_by_home_ou};
-                    if ($args->{org} and defined($restrict_by_ou) and $restrict_by_ou =~ /^t/i) {
-                        my $descendants = $U->get_org_descendants($args->{org});
-                        unless (grep $user->[0]->home_ou, @$descendants) {
-                            $logger->debug("Matching user does not belong to this org, aborting");
-                            return OpenILS::Event->new( 'LOGIN_FAILED' );
+                    if (defined($restrict_by_ou) and $restrict_by_ou =~ /^t/i) {
+                        my $home_ou = $user->[0]->home_ou;
+                        my $allowed = 0;
+                        # disallow auth if user's home library is not one of the org_units for this authenticator
+                        if ($authenticator->org_units) {
+                            if (grep(/^all$/, @{$authenticator->org_units})) {
+                                $allowed = 1;
+                            } else {
+                                foreach my $org (@{$authenticator->org_units}) {
+                                    my $allowed_orgs = $U->get_org_descendants($org);
+                                    if (grep(/^$home_ou$/, @$allowed_orgs)) {
+                                        $allowed = 1;
+                                        last;
+                                    }
+                                }
+                            }
+                            if (!$allowed) {
+                                $logger->debug("Auth disallowed for matching user's home library, aborting");
+                                return OpenILS::Event->new( 'LOGIN_FAILED' );
+                            }
                         }
                     }
                     $args->{user_id} = $user->[0]->id;

commit c485b3dcac422ad11e0cdb9d74f674e8c9f9355c
Author: Jeff Davis <jeff.davis at bc.libraries.coop>
Date:   Fri Feb 8 13:59:14 2019 -0800

    LP#1786552: optionally restrict auth_proxy login by home OU
    
    This adds a new restrict_by_home_ou setting to auth_proxy authenticator
    config.  When enabled, if the login request includes an org param, the
    authenticator will refuse to authenticate a user unless their home OU
    matches or is a descendant of that org; login fails and auth_proxy
    proceeds to the next configured authenticator.
    
    Signed-off-by: Jeff Davis <jeff.davis at bc.libraries.coop>
    Signed-off-by: Galen Charlton <gmc at equinoxinitiative.org>

diff --git a/Open-ILS/examples/opensrf.xml.example b/Open-ILS/examples/opensrf.xml.example
index b0ed2553be..eb875b1116 100644
--- a/Open-ILS/examples/opensrf.xml.example
+++ b/Open-ILS/examples/opensrf.xml.example
@@ -555,6 +555,7 @@ vim:et:ts=4:sw=4:
                                 <unit>103</unit>
                                 <unit>104</unit>
                             </org_units>
+                            <restrict_by_home_ou>false</restrict_by_home_ou>
                         </authenticator>
                         -->
                         <!-- 'native' is a proxied version of Evergreen's standard authentication -->
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy.pm
index 9b5198e4c7..d0fcbe7881 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy.pm
@@ -260,10 +260,14 @@ sub login {
                     $logger->debug("Authenticated username '" . $args->{'username'} . "' has no Evergreen account, aborting");
                     return OpenILS::Event->new( 'LOGIN_FAILED' );
                 } else {
-                    # TODO: verify that this authenticator is allowed to do auth
-                    # for the specified username (i.e. if the authenticator is for
-                    # Library A only, it shouldn't be able to do auth for
-                    # Library B's users)
+                    my $restrict_by_ou = $authenticator->{restrict_by_home_ou};
+                    if ($args->{org} and defined($restrict_by_ou) and $restrict_by_ou =~ /^t/i) {
+                        my $descendants = $U->get_org_descendants($args->{org});
+                        unless (grep $user->[0]->home_ou, @$descendants) {
+                            $logger->debug("Matching user does not belong to this org, aborting");
+                            return OpenILS::Event->new( 'LOGIN_FAILED' );
+                        }
+                    }
                     $args->{user_id} = $user->[0]->id;
                 }
 

commit 3a7ca4a2c6c3d6ea893d13a38179e9b4a26e523a
Author: Jeff Davis <jdavis at sitka.bclibraries.ca>
Date:   Tue Oct 16 18:24:00 2018 -0700

    LP#1786552: LDAP bind user option
    
    Signed-off-by: Jeff Davis <jdavis at sitka.bclibraries.ca>
    Signed-off-by: Galen Charlton <gmc at equinoxinitiative.org>

diff --git a/Open-ILS/examples/opensrf.xml.example b/Open-ILS/examples/opensrf.xml.example
index 156562b82b..b0ed2553be 100644
--- a/Open-ILS/examples/opensrf.xml.example
+++ b/Open-ILS/examples/opensrf.xml.example
@@ -544,6 +544,7 @@ vim:et:ts=4:sw=4:
                             <basedn>ou=people,dc=domain,dc=com</basedn>
                             <authid>cn=username,ou=specials,dc=domain,dc=com</authid>
                             <id_attr>uid</id_attr>
+                            <bind_attr>uid</bind_attr>
                             <password>my_ldap_password_for_authid_user</password>
                             <login_types>
                                 <type>staff</type>
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy.pm
index 1f7832c653..9b5198e4c7 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy.pm
@@ -176,6 +176,10 @@ sub login {
     return OpenILS::Event->new( 'LOGIN_FAILED' )
       unless (&enabled() and ($args->{'username'} or $args->{'barcode'}));
 
+    # provided username may not be the user's actual EG username;
+    # hang onto the provided value (if any) so we can use it later
+    $args->{'provided_username'} = $args->{'username'};
+
     if ($args->{barcode} and !$args->{username}) {
         # translate barcode logins into username logins by locating
         # the matching card/user and collecting the username.
@@ -232,10 +236,15 @@ sub login {
         if ($code) {
             push @error_events, $event;
         } elsif (defined $code) { # code is '0', i.e. SUCCESS
-            if (exists $event->{'payload'}) { # we have a complete native login
+            if ($authenticator->name eq 'native' and exists $event->{'payload'}) { # we have a complete native login
                 return $event;
             } else { # create an EG session for the successful external login
-                #
+                # if external login returns a payload, that payload is the
+                # user's Evergreen username
+                if ($event->{'payload'}) {
+                    $args->{'username'} = $event->{'payload'};
+                }
+
                 # before we actually create the session, let's first check if
                 # Evergreen thinks this user is allowed to login
                 #
@@ -251,6 +260,10 @@ sub login {
                     $logger->debug("Authenticated username '" . $args->{'username'} . "' has no Evergreen account, aborting");
                     return OpenILS::Event->new( 'LOGIN_FAILED' );
                 } else {
+                    # TODO: verify that this authenticator is allowed to do auth
+                    # for the specified username (i.e. if the authenticator is for
+                    # Library A only, it shouldn't be able to do auth for
+                    # Library B's users)
                     $args->{user_id} = $user->[0]->id;
                 }
 
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy/LDAP_Auth.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy/LDAP_Auth.pm
index a180e3a477..863846a70a 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy/LDAP_Auth.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/AuthProxy/LDAP_Auth.pm
@@ -34,15 +34,50 @@ sub authenticate {
     my $authid      = $self->{'authid'};
     my $authid_pass = $self->{'password'};
     $id_attr        = $self->{'id_attr'} || $id_attr;
+    my $bind_attr   = $self->{'bind_attr'} || $id_attr; # use id_attr to bind if bind_attr not set
+
+    # bind_attr: name of LDAP attribute containing user's LDAP username
+    # id_attr: name of LDAP attribute containing user's Evergreen username
+    #
+    # Normally the LDAP username *is* the Evergreen username, in which case
+    # we don't need the extra step of getting the username from the LDAP entry.
+    # Thus, bind_attr and id_attr are the same.  (This is the default scenario.)
+    #
+    # However, suppose we have two college libraries in a consortium.  Each
+    # college has its own LDAP-based SSO solution.  An LDAP username like
+    # "jsmith" may be in use at both libraries, for two different patrons.
+    # In this case, we can't use the LDAP username as the EG username, since
+    # every patron must have a unique username in EG.
+    #
+    # Here's how we handle this second scenario:
+    #
+    # 1. The user logs in with their LDAP username.
+    # 2. EG makes a bind request to the LDAP server using the LDAP username,
+    # which is in the LDAP attribute specified by bind_attr.
+    # 3. If the bind succeeds, we pull the user's EG username from the LDAP
+    # attribute specified by id_attr, and pass it along so that EG looks up the
+    # correct user.
+    #
+    # If bind_attr is not set, or if it specifies the same LDAP attribute as
+    # id_attr, we fallback to the default scenario.
+    #
+    my $username_from_ldap = $bind_attr eq $id_attr ? 0 : 1;
+
+    # When the EG username is retrieved from the LDAP server, we want to ensure
+    # that we bind using the actual username provided by the user.
+    if ($username_from_ldap) {
+        $username = $args->{'provided_username'} || $username;
+    }
 
     my $ldap;
+    my $ldap_search;
     if ( $ldap = Net::LDAP->new($hostname) ) {
         $hostname_is_ldap = 1;
         if ( $ldap->bind( $authid, password => $authid_pass )->code == 0 ) {
             $reached_ldap = 1;
             # verify username and lookup user's DN
-            my $ldap_search = $ldap->search( base => $basedn,
-                                             filter => "($id_attr=$username)" );
+            $ldap_search = $ldap->search( base => $basedn,
+                                             filter => "($bind_attr=$username)" );
             if ( $ldap_search->count != 0 ) {
                 $user_in_ldap = 1;
 
@@ -57,7 +92,12 @@ sub authenticate {
     }
 
     if ( $login_succeeded ) {
-        return OpenILS::Event->new('SUCCESS');
+        if ($username_from_ldap) {
+            my $id_attr_val = $ldap_search->entry(0)->get_value($id_attr);
+            return OpenILS::Event->new('SUCCESS', payload => $id_attr_val);
+        } else {
+            return OpenILS::Event->new('SUCCESS');
+        }
     } elsif ( !$hostname_is_ldap ) {
         # TODO: custom failure events?
         $logger->debug("User login failed: Incorrect LDAP hostname");

-----------------------------------------------------------------------

Summary of changes:
 Open-ILS/examples/opensrf.xml.example              |  2 +
 .../perlmods/lib/OpenILS/Application/AuthProxy.pm  | 36 ++++++++++++++++-
 .../lib/OpenILS/Application/AuthProxy/LDAP_Auth.pm | 46 ++++++++++++++++++++--
 .../Administration/ldap_bind_user.adoc             | 34 ++++++++++++++++
 4 files changed, 113 insertions(+), 5 deletions(-)
 create mode 100644 docs/RELEASE_NOTES_NEXT/Administration/ldap_bind_user.adoc


hooks/post-receive
-- 
Evergreen ILS


More information about the open-ils-commits mailing list