Reauthentication via pop up basic auth dialog

Searched a bit and couldn’t find anything that seemed to match my situation, but maybe I wasn’t using the right search terms. Apologies if this has been asked somewhere else.

I’m running ROR Pro version 1.17.6 with Elasticsearch 6.6.0 on CentOS 7. Using LDAP auth, I initially get the login page, and am able to successfully login and use things. However, over the last several days, if I don’t use it frequently (maybe 30 minutes idle) I get a pop-up basic auth dialog when I try to do something else. Earlier this morning it happened with this error in the logs:

[2019-05-31T14:07:54,618][INFO ][t.b.r.a.l.AclLoggingDecorator] [elasticsearch1-0.example.com] FORBIDDEN by default req={  ID:46080135-1691240364#220385953,  TYP:SearchRequest,  CGR:N/A,  USR:[user not logged],  BRS:false,  KDX:null,  ACT:indices:data/read/search,  OA:1.2.3.4/32,  XFF:null,  DA:1.2.3.4/32,  IDX:<N/A>,  MET:POST,  PTH:/.kibana/_search?size=10000&from=0&_source=index-pattern.title%2Cindex-pattern.type%2Cnamespace%2Ctype%2Ctitle%2Ctype&rest_total_hits_as_int=true,  CNT:<OMITTED, LENGTH=193.0 B> ,  HDR:Connection=keep-alive, Content-Length=193, Host=elasticsearch1-0.example.com:9200, authorization=Basic Y2hlZXJzY2hhcDoxOTUwIGJyb3VnaHQgdGhlIEEtYm9tYg==, content-type=application/json,  HIS:[local-admin->[auth_key_unix->false]], [local-logstash->[auth_key_unix->false]], [local-kibana->[auth_key_unix->false]], [local-puppet->[auth_key_unix->false]], [elastalert->[auth_key_unix->false]], [ldap-admin->[ldap_auth->false]], [ldap-all->[ldap_auth->false]], [localhost->[hosts->false]]  }

If I resupply my LDAP creds, it works. I just went back to do something else and it reauthenticated me again, this time with the following errors:

[2019-05-31T14:47:18,763][ERROR][t.b.r.a.b.d.l.i.UnboundidLdapAuthorizationService] [elastic1-0.example.com] LDAP getting user operation failed.
tech.beshu.ror.acl.blocks.definitions.ldap.implementations.LdapUnexpectedResult: null
	at 
...
{snip}
...
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_212]
[2019-05-31T14:47:18,808][INFO ][t.b.r.a.l.AclLoggingDecorator] [elastic1-0.example.com] FORBIDDEN by default req={  ID:134819455-1691240364#221560180,  TYP:SearchRequest,  CGR:N/A,  USR:[user not logged],  BRS:false,  KDX:null,  ACT:indices:data/read/search,  OA:10.2.111.52/32,  XFF:null,  DA:10.2.111.45/32,  IDX:<N/A>,  MET:POST,  PTH:/.kibana/_search?size=10000&from=0&_source=index-pattern.title%2Cindex-pattern.type%2Cnamespace%2Ctype%2Ctitle%2Ctype&rest_total_hits_as_int=true,  CNT:<OMITTED, LENGTH=193.0 B> ,  HDR:Connection=keep-alive, Content-Length=193, Host=elastic1-0.example.com:9200, authorization=Basic OTUwIGJyb3VnaHQgdGhlIEEtYm9tYg==, content-type=application/json,  HIS:[local-admin->[auth_key_unix->false]], [local-logstash->[auth_key_unix->false]], [local-kibana->[auth_key_unix->false]], [local-puppet->[auth_key_unix->false]], [elastalert->[auth_key_unix->false]], [ldap-admin->[ldap_auth->false]], [ldap-all->[ldap_auth->false]], [localhost->[hosts->false]]  }

Couldn’t post all the stack traces because of limitations of the forum, so the full log output is available here: readonlyrest LDAP reauth errors · GitHub

Obviously I realize that this could be an issue with our LDAP servers, but other web UIs that use the exact same auth configuration (Icinga2 running Thruk as a frontend - the LDAP config for that is what was used for the RoR config) don’t encounter the same problem. Is this a timeout issue on the LDAP auth config? What has me concerned is it seems like it’s happening more frequently as time passes since I first observed it a week or so ago.

Here’s my ROR config yaml from the puppet ERB template, so the key config bits haven’t been swapped in inside the <%= ... %> code. This config hasn’t been modified for about a month since I got ti working reliably.

# yamllint disable rule:line-length
# THIS FILE IS PROVISIONED BY PUPPET
# However, once it gets loaded into the .readonlyrest index,
#  you might need to use an admin account to log into Kibana
#  and choose "Load default" from the "ReadonlyREST" tab.
# Alternately, you can use the "update-ror" script in ~cheerschap/bin/
readonlyrest:
  enable: true
  response_if_req_forbidden: Forbidden by ReadonlyREST plugin
  ssl:
    enable: true
    keystore_file: "elasticsearch.jks"
    keystore_pass: "<%= @es_key_pass %>"
    key_pass: "<%= @es_key_pass %>"
  access_control_rules:
    # LOCAL: Kibana admin account
    - name: "local-admin"
      auth_key_unix: "admin:<%= @admin_hash %>"
      kibana_access: admin
    # LOCAL: Logstash servers inbound access
    - name: "local-logstash"
      auth_key_unix: "logstash:<%= @logstash_hash %>"
      # Local accounts for routine access should have less verbisity
      #  to keep the amount of logfile noise down
      verbosity: error
    # LOCAL: Kibana server
    - name: "local-kibana"
      auth_key_unix: "kibana:<%= @kibana_hash %>"
      verbosity: error
    # LOCAL: Puppet communication
    - name: "local-puppet"
      auth_key_unix: "puppet:<%= @puppet_hash %>"
      verbosity: error
    # LOCAL: Elastalert
    - name: "elastalert"
      auth_key_unix: "elastalert:<%= @elastalert_hash %>"
      verbosity: error
    # LDAP: kibana-admin group
    - name: "ldap-admin"
      kibana_access: admin
      ldap_auth:
        name: "ldap1"
        groups: ["kibana-admin"]
      type: allow
    # LDAP for everyone else
    - name: "ldap-all"
      # possibly include: "kibana:dev_tools",
      kibana_hide_apps: ["readonlyrest_kbn", "timelion", "kibana:management", "apm", "infra:home", "infra:logs"]
      ldap_auth:
        name: "ldap1"
        groups: ["kibana-admin", "admins", "prod-admins", "devqa", "development", "ipausers"]
      type: allow
    # Allow localhost
    - name: "localhost"
      hosts: [127.0.0.1]
  # Define the LDAP connection
  ldaps:
    - name: ldap1
      host: "<%= @ipa_server %>"
      port: 636
      bind_dn: "<%= @bind_dn %>"
      bind_password: "<%= @bind_pass %>"
      ssl_enabled: true
      ssl_trust_all_certs: true
      search_user_base_DN: "<%= @user_search_dn %>"
      search_groups_base_DN: "<%= @group_search_dn %>"
      user_id_attribute: "uid"
      unique_member_attribute: "member"
      connection_pool_size: 10
      connection_timeout_in_sec: 30
      request_timeout_in_sec: 30
      cache_ttl_in_sec: 60
      group_search_filter: "(objectclass=top)"
      group_name_attribute: "cn"

I’m also curious if it thinks it needs to reauthenticate why it uses the basic auth vs. redirecting to the main login page. It’s a small thing but an annoying inconsistency that I know is going to result in questions from the end users.

@cmh thanks for detailed explanation of your problem. As you’ve already noticed it could be some temporary issue with LDAP servers. That’s why you saw LdapUnexpectedResult exception in logs. Your request was forbidden because no rule was matched. ROR plugin sent HTTP 401 response with “WWW-Authenticate:basic” and that’s how your browser was instructed to show basic auth dialog.

Notice that this is not an issue. The same situation you will experience when eg. LDAP admin will change your user password. You will be asked for credentials once again.

You should not experience this behaviour with Kibana plugin, because user session is managed using cookie, so the issue doesn’t exist.

Thanks for log. We’ll try to make it more concise.

Maybe I’m not understanding what you’re saying but this is with the RoR Kibana plugin where I’m seeing this - I’m in the Kibana UI and have authenticated, but then get the pop-up in my browser. This is why I’m concerned, I know users will be confused and ask questions when an active session doesn’t expire (at least not according to any messages on the screen) and a different type of auth pops up. If a cookie has been saved for this session, then it doesn’t seem like it’s working.

I thought you are using ROR without Kibana plugin. If it also doesn’t work in this case, maybe @sscarduzio can help

if you use the kibana plugin, set this in readonlyrest.yml (or in the settings editor of the ROR Kibana app):

readonlyrest:
    prompt_for_basic_auth: false 

Now when LDAP is unreachable, or credentials change on LDAP, or the user tries to perform an unauthorized action, their cookie will be deleted.

If you have a backup LDAP server, add it to configurations, we support multiple servers and HA (high availability) strategies.

 # High availability LDAP settings (using "hosts", rather than "host")
    - name: ldap2
      hosts:                                                        # HA style, alternative to "host"
      - "ldaps://ssl-ldap2.foo.com:636"                             # can use ldap:// or ldaps:// (for ssl)
      - "ldaps://ssl-ldap3.foo.com:636"                             # the port is declared in line
      ha: "ROUND_ROBIN"                                             # optional, default "FAILOVER"
      ....

As seen in the documentation.

1 Like