elasticsearch-java icon indicating copy to clipboard operation
elasticsearch-java copied to clipboard

Serialized FieldRule of PutRoleMappingRequest can't be parsed by Elasticsearch server

Open GeBeater opened this issue 1 year ago • 1 comments

Java API client version

8.9.1

Java version

17

Elasticsearch Version

8.9.2

Problem description

I am going to use the ElasticsearchSecurityAsyncClient for a PutRoleMappingRequest to create the following role mapping like described in the Elasticsearch's - Authorizing with the role mapping API - docu.

{
    "roles": [
        "tenant"
    ],
    "rules": {
        "all": [
            {
                "field": {
                    "realm.name": "jwt1"
                }
            },
            {
                "field": {
                    "username": "*"
                }
            }
        ]
    },
    "enabled": true
}

I am using a custom ElasticsearchTransport impl (that is based on Spring's WebClient) but with the JacksonJsonpMapper provided by the elasticsearch-java client library.

Unfortunately the Java client producing the following request which ends in a x_content_parse_exception (failed to parse rules expression. expected a field value but found [START_OBJECT] instead).

{
    "enabled": true,
    "roles": [
        "tenant"
    ],
    "rules": {
        "all": [
            {
                "field": {
                    "realm": {
                        "name": "jwt1"
                    }
                }
            },
            {
                "field": {
                    "username": "*"
                }
            }
        ]
    }
}

Expected behavior:

It is possible to create a FieldRule realm name that will be serialized to realm.name as property with a string value instead of a property "realm" with an object node.

GeBeater avatar Sep 19 '23 15:09 GeBeater

This is still broken in elasticsearch-java:8.11.1

kstec avatar Nov 29 '23 16:11 kstec

Hello! This is the idiomatic way of creating a role mapping with the java client:

esClient.security().putRoleMapping(rm -> rm
    .name("my_role_mapping")
    .enabled(true)
    .roles("tenant")
    .rules(ru -> ru
        .all(List.of(
              RoleMappingRule.of(
              rmr -> rmr
                  .field(f -> f
                      .username(List.of("*")))),
              RoleMappingRule.of(
              rmr1 -> rmr1
                   .field(f -> f
                       ._custom("realm.name","jwt1")))))));

We'll check on why it doesn't work with the raw json, but in the meantime this should work.

l-trotta avatar Apr 24 '24 08:04 l-trotta

Thanks @l-trotta. That _custom appears to be a new addition provided by this commit https://github.com/elastic/elasticsearch-java/commit/d78feca1695513c74e3fbfcc6c4be187bee2e38c

Thanks!

kstec avatar Apr 25 '24 14:04 kstec

@kstec thanks for checking, yes that commit fixes the issue!

l-trotta avatar Apr 29 '24 10:04 l-trotta