# How to create custom plugin for LDAP only for authorization

**URL:** <https://discuss.elastic.co/t/how-to-create-custom-plugin-for-ldap-only-for-authorization/45311>\
**Category:** Elasticsearch\
**Tags:** elastic-stack-security\
**Created:** [March 24, 2016, 7:38am UTC](https://discuss.elastic.co/t/how-to-create-custom-plugin-for-ldap-only-for-authorization/45311 "2016-03-24T07:38:30Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![ravi\_yadav](https://avatars.discourse-cdn.com/v4/letter/r/e9bcb4/32.png) [@ravi\_yadav](https://discuss.elastic.co/u/ravi_yadav)\
**Post date:** [March 24, 2016, 7:38am UTC](https://discuss.elastic.co/t/how-to-create-custom-plugin-for-ldap-only-for-authorization/45311/1 "2016-03-24T07:38:30Z")

</div>

Tools used : 1. Elasticsearch 2.1 with Shield 2.1 2. DgLux as a front end report generation tool 3. Company LDAP to authenticate user against groups

I'm trying to create a custom plugin which should use LDAP only for authorization.

Authentication is already happening via a third party LDAP utility to login into the system.

Every request that goes from DgLux to Elasticsearch will be authenticated and authorized to make sure that the user can perform specific task on the indices.

My requirement is that request will only have user in the header and shield shouldn't try to authenticate the request, only authorization should happen.

How can I built that plugin?

---

<div class="post-metadata">

**Author:** ![jaymode](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jaymode/32/50103_2.png) [@jaymode](https://discuss.elastic.co/u/jaymode)\
**Post date:** [March 24, 2016, 10:50am UTC](https://discuss.elastic.co/t/how-to-create-custom-plugin-for-ldap-only-for-authorization/45311/2 "2016-03-24T10:50:24Z")

</div>

If you have control over the header name that is passed to elasticsearch, you can use the [run as](https://www.elastic.co/guide/en/shield/2.1/submitting-requests-for-other-users.html) feature of Shield. For this to work, DgLux would need to send authentication credentials for a user that had the ability to run as the actual user in Shield. In the configuration for Shield, you would define an LDAP realm (with a bind\_dn) that will be used to look up the user in the run as header and could authorize the user. Note: you could use anonymous access for DgLux but that would not be very secure unless you can guarantee that DgLux is the only thing communicating directly with elasticsearch.

If that will not work for you, I suggest you take a look at [custom realms](https://www.elastic.co/guide/en/shield/2.1/custom-realms.html) and the [example for 2.1.0](https://github.com/elastic/shield-custom-realm-example/tree/v2.1.0). Your custom realm would [look for the header](https://github.com/elastic/shield-custom-realm-example/blob/v2.1.0/src/main/java/org/elasticsearch/example/realm/CustomRealm.java#L92-L109) passed from DgLux and convert that into a [specific authentication token that your custom realm understands](https://github.com/elastic/shield-custom-realm-example/blob/v2.1.0/src/main/java/org/elasticsearch/example/realm/CustomRealm.java#L81-L90). The token would then get passed into the [authenticate method](https://github.com/elastic/shield-custom-realm-example/blob/v2.1.0/src/main/java/org/elasticsearch/example/realm/CustomRealm.java#L130-L146) by Shield and this is where you would implement code to lookup the user in LDAP and map them to the appropriate Shield role names. In this scenario, you would also want a way to authenticate the requests coming from DgLux otherwise this will not be secure since anyone can pass in the header and get into elasticsearch.

---

<div class="post-metadata">

**Author:** ![ravi\_yadav](https://avatars.discourse-cdn.com/v4/letter/r/e9bcb4/32.png) [@ravi\_yadav](https://discuss.elastic.co/u/ravi_yadav)\
**Post date:** [March 24, 2016, 1:59pm UTC](https://discuss.elastic.co/t/how-to-create-custom-plugin-for-ldap-only-for-authorization/45311/3 "2016-03-24T13:59:51Z")

</div>

We were already working on run\_as functionality and found that it is not feasible because of two reasons:

1. For run\_as functionality we need to pass a generic user with password which should have same access as the DgLux user. That means we need to do it dynamically as DgLux user which is supposed to get admin access can not run\_as a restricted user from shield so we cannot hard code the generic user name and password for all requests.

2. DgLux is unable to pass any additional parameters/headers.

So the only solution we are thinking is to develop a custom plugin and here are few thoughts we have:

1. Override the default LDAP realm to change its functionality for authentication and authorization.
2. For Authentication create a session using generic username and password which is defined in LDAP
3. For Authorization set supportsUnauthenticatedSession=true from SessionFactory class so that it will only use the username to create LDAP session and perform role mappings.

For above feature we are trying use [custom realm example](https://www.elastic.co/guide/en/shield/2.1/custom-realms.html) CustomRealm.java to override authentication and authorization logics and CustomRealmFactory.java to instantiate CustomRealm. But there is no success yet. Any help would be appreciated.

---

<div class="post-metadata">

**Author:** ![skearns](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/skearns/32/125945_2.png) [@skearns](https://discuss.elastic.co/u/skearns)\
**Post date:** [March 24, 2016, 2:18pm UTC](https://discuss.elastic.co/t/how-to-create-custom-plugin-for-ldap-only-for-authorization/45311/4 "2016-03-24T14:18:21Z")

</div>

> [@ravi\_yadav](#):
>
> For run\_as functionality we need to pass a generic user with password which should have same access as the DgLux user. That means we need to do it dynamically as DgLux user which is supposed to get admin access can not run\_as a restricted user from shield so we cannot hard code the generic user name and password for all requests.

I'm not sure I fully understand this, but I wanted to clarify how run-as works. Let's use a quick example: when using the run-as feature, you make a search request as the user `my_application`. As part of the request, set the header `es-shield-runas-user: skearns`. This tells Shield that the `my_application` user would like to run a request _as_ the user `skearns`.

The `my_application` user does not need to have the same level of permissions as `skearns`. In fact, the `my_application` user only needs permission to run\_as the user `skearns`, which you could achieve by granting the `my_application` user a role that only grants run\_as capabilities, like this:

```auto
run_as_role:
    run_as: skearns

```

> [@ravi\_yadav](#):
>
> DgLux is unable to pass any additional parameters/headers.

What other headers do you want to pass that you cannot?

---

<div class="post-metadata">

**Author:** ![ravi\_yadav](https://avatars.discourse-cdn.com/v4/letter/r/e9bcb4/32.png) [@ravi\_yadav](https://discuss.elastic.co/u/ravi_yadav)\
**Post date:** [March 24, 2016, 4:09pm UTC](https://discuss.elastic.co/t/how-to-create-custom-plugin-for-ldap-only-for-authorization/45311/5 "2016-03-24T16:09:45Z")

</div>

My understanding of run\_as functionality, based on what i have red and tested, is as per below syntax:

Curl -H "es-shield-runas-user: {Outside user who need access to cluster}" -u {Generic user defined in shield to be used for authentication} : {password for generic user defined in shield} http://{host}:{port}

Please correct me if i'm wrong.

---

<div class="post-metadata">

**Author:** ![jaymode](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jaymode/32/50103_2.png) [@jaymode](https://discuss.elastic.co/u/jaymode)\
**Post date:** [March 25, 2016, 11:45am UTC](https://discuss.elastic.co/t/how-to-create-custom-plugin-for-ldap-only-for-authorization/45311/6 "2016-03-25T11:45:23Z")

</div>

Your understanding of run as is correct. The only think I would add is that you can use PKI to authenticate rather than a preconfigured user; not sure if DgLux would support that...

> [@ravi\_yadav](#):
>
> So the only solution we are thinking is to develop a custom plugin and here are few thoughts we have:
> 
> Override the default LDAP realm to change its functionality for authentication and authorization.  
> For Authentication create a session using generic username and password which is defined in LDAP  
> For Authorization set supportsUnauthenticatedSession=true from SessionFactory class so that it will only use the username to create LDAP session and perform role mappings.

It sounds to me like you are trying to extend existing Shield classes? This really is not supported and there are no API guarantees for these classes; in a bugfix release a change to these classes could break your realm. These classes are not intended to be used in a custom realm.

Instead, I would implement a custom realm that does exactly what you need. The interfaces/classes exposed in the custom realm example are what I would consider stable and we will try to not break the API for these in minor releases.

> [@ravi\_yadav](#):
>
> For above feature we are trying use custom realm example CustomRealm.java to override authentication and authorization logics and CustomRealmFactory.java to instantiate CustomRealm. But there is no success yet. Any help would be appreciated.

You will need to provide more information. For things like this, "there is no success yet" does not provide any information that enables us to help. Please provide **all** of the details of what you have done and if possible code snippets.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 6, 2017, 1:45pm UTC](https://discuss.elastic.co/t/how-to-create-custom-plugin-for-ldap-only-for-authorization/45311/7 "2017-07-06T13:45:41Z")

</div>


