diff --git a/README.md b/README.md index 60d7e77..13eb1fe 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,10 @@ Use the LDAP strategy as a middleware in your application: :uid => 'sAMAccountName', :name_proc => Proc.new {|name| name.gsub(/@.*$/,'')} :bind_dn => 'default_bind_dn' - :password => 'password' + :password => 'password', + :group => 'group' -All of the listed options are required, with the exception of :title, :name_proc, :bind_dn, and :password. +All of the listed options are required, with the exception of :title, :name_proc, :bind_dn, :password and :group. Allowed values of :method are: :plain, :ssl, :tls. :bind_dn and :password is the default credentials to perform user lookup. @@ -38,6 +39,10 @@ Allowed values of :method are: :plain, :ssl, :tls. Use them to initialize a SASL connection to server. If you are not familiar with these authentication methods, please just avoid them. +:group will additionally allow users to check whether the user belongs to a specific group. After a user has been + authenticated, group will be checked. If the user does not belong to the specified group, the user will be redirected + to /auth/failure with the message, :invalid_group + Direct users to '/auth/ldap' to have them authenticated via your company's LDAP server. diff --git a/lib/omniauth/strategies/ldap.rb b/lib/omniauth/strategies/ldap.rb index 2ba577a..cade6a5 100644 --- a/lib/omniauth/strategies/ldap.rb +++ b/lib/omniauth/strategies/ldap.rb @@ -24,6 +24,7 @@ class LDAP option :method, :plain option :uid, 'sAMAccountName' option :name_proc, lambda {|n| n} + option :group def request_phase OmniAuth::LDAP::Adaptor.validate @options @@ -42,6 +43,11 @@ def callback_phase @ldap_user_info = @adaptor.bind_as(:filter => Net::LDAP::Filter.eq(@adaptor.uid, @options[:name_proc].call(request['username'])),:size => 1, :password => request['password']) return fail!(:invalid_credentials) if !@ldap_user_info + # If group is specified in options, validate membership + if @options[:group] + return fail!(:invalid_group) unless is_member?(@ldap_user_info) + end + @user_info = self.class.map_user(@@config, @ldap_user_info) super rescue Exception => e @@ -86,6 +92,15 @@ def self.map_user(mapper, object) def missing_credentials? request['username'].nil? or request['username'].empty? or request['password'].nil? or request['password'].empty? end # missing_credentials? + + def is_member?(ldap_user_info) + ldap_user_info.memberof.each do |value| + group_parts = value.split(',') + expected_group = group_parts[0].match(/CN=(.+)/) + return true if expected_group[1] == options[:group] + end + return false + end # is_member?(Net::LDAP::Entry) end end end