Indices variable substitution and external_authentication

Hi again,

Given the following configuration:

  - name: testrule
    type: allow
    auth_key: user:passwd
    indices: ["@{user}__*"]

I can access the index named user__testindex. For example the command:

curl -XGET -u user 'https://localhost:9200/user__testindex/_mapping?pretty'

is permitted:

[2017-05-22T14:02:29,632][INFO ][o.e.p.r.a.ACL            ] request: { ID:1018362977-680753494, TYP:GetIndexRequest, USR:user, BRS:true, ACT:indices:admin/get, OA:172.17.0.1, IDX:user__testindex, MET:GET, PTH:/user__testindex/_mapping, CNT:<OMITTED, LENGTH=0>, HDR:Accept,Authorization,content-length,Host,User-Agent,  HIS:[testrule->[indices->true, auth_key->true]] } matched block: testrule match: true}

However, if I use external_authentication instead of auth_key, the user variable doesn’t seem to be substituted in the indices rule. If I change the configuration to:

  - name: testrule
    type: allow
    external_authentication: "testauth"
    indices: ["@{user}__*"]

  external_authentication_service_configs:

  - name: "testauth"
    [external authentication configuration, which accepts user:passwd]

then the same command fails because there are no matching indices:

[2017-05-22T14:09:35,405][INFO ][o.e.p.r.e.IndexLevelActionFilter] [WA3PECj] forbidden request: { ID:1466340573-244481894, TYP:GetIndexRequest, USR:user(?), BRS:true, ACT:indices:admin/get, OA:172.17.0.1, IDX:user__testindex, MET:GET, PTH:/user__testindex/_mapping, CNT:<OMITTED, LENGTH=0>, HDR:Accept,Authorization,content-length,Host,User-Agent,  HIS:[testrule->[indices->false]] } Reason: null (null)

If I comment out the indices line, the operation is permitted again (but that doesn’t check the index name of course).

Is this supposed to work, i.e. ${user} variable substitution when using external_authentication?

Thanks @krbr, great analysis. I was able to reproduce this. However, I’m not sure I understand anymore the code.
Hey @coutoPL could you spend a few words on the Value stuff you introduced in the refactoring?

Value is an interface which represents value that might be resolvable. So it may be in one of two states: Variable and Const (both implement the Value interface). We create value from string using static method fromString(str: String): Value[T]. When we need inner value T we have to call getValue and pass resolver.

I do it to explicitly mark string as a resolvable value. Before logic which decides if string is resolvable was placed in rule. Now the logic is placed in Value interface. And rule’s just resolving strings. When you check rule settings, you see that its value is resolvable or is just static string.

OK I discovered what’s wrong with this. It’s about the rules ordering: the external authentication is evaluated after the indices rule.
https://github.com/sscarduzio/elasticsearch-readonlyrest-plugin/blob/master/core/src/main/java/org/elasticsearch/plugin/readonlyrest/acl/blocks/rules/RulesOrdering.java#L76

I tested this is working after pushing all the authentication (sync and async) rules at the top.

I’ve just updated to the latest version of the plugin, and can confirm it’s working now, thanks!

1 Like