Skip to content

Conversation

@geoffmore
Copy link

The context behind this PR is my desire to support token based authentication for API calls.

The following changes were made to support token authentication according to token documentation.

elasticsearch.go:

  • Add Token field to elasticsearch.Config struct
  • In function elasticsearch.NewClient, add Token field in call to estransport.New for initialization of variable tp

estransport/estransport.go

  • Add Token field to estransport.Config struct
  • Add token field to estransport.Client struct
  • In function estransport.New, add token field to Client return
  • In func (c *Client) setAuthorization(u *url.URL, req *http.Request) *http.Request, add logic supporting token headers similar what is done for apikey.

@karmi
Copy link
Contributor

karmi commented Aug 27, 2019

Hello, thanks for the patch! I'm on vacation currently, I'll have a look when I'm back. The changes themselves look good, I'll just have to think through the order of precedence between the various authentication values.

@geoffmore
Copy link
Author

@karmi Did the precedence match what you expected?

@karmi
Copy link
Contributor

karmi commented Nov 3, 2019

Hi, sorry for such a long delay! I've been thinking about the feature a little bit more, and I've realized it would actually make the client diverge from the other official clients, which don't support such a feature out of the box.

Since Elasticsearch itself doesn't support a token-based authentication, and it's applicable only when some kind of proxy sits in front of it, I think it qualifies as a "custom environment". Therefore, I'd suggest creating a custom transport, wrapping the default one, and setting the request header — as in the following example:

//+build ignore

package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/estransport"
)

const (
	serverToken = "abc123"
	clientToken = "xyz456" // <<< Change to the same value for successful authorization
)

type AuthorizedTransport struct{}

func (t *AuthorizedTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	req.Header.Set("Authorization", "Bearer "+clientToken)
	fmt.Println(">>> ", req.Header.Get("Authorization"))
	return http.DefaultTransport.RoundTrip(req)
}

func main() {
	log.SetFlags(0)

	defaultHandler := func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("<<< ", r.Header.Get("Authorization"))
		if r.Header.Get("Authorization") != "Bearer "+serverToken {
			http.Error(w, "Invalid credentials", 403)
			return
		}
		fmt.Fprintln(w, "OK")
	}

	go func() {
		log.Fatalln(http.ListenAndServe("localhost:10100", http.HandlerFunc(defaultHandler)))
	}()

	es, _ := elasticsearch.NewClient(
		elasticsearch.Config{
			Addresses: []string{"http://localhost:10100"},
			Transport: &AuthorizedTransport{},
			// >>>>> Wrap the transport >>>>>>>>>>>>>>>>>>>>>>>>
			Logger: &estransport.ColorLogger{Output: os.Stdout},
			// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		})

	res, err := es.Info()
	if err != nil {
		log.Fatalf("Error getting response: %v", err)
	}
	defer res.Body.Close()

	if res.IsError() {
		log.Fatalf("Error response: %s", res)
	}

	log.Println(res)
}

With this reasoning, I'd like to close the PR without merging. Please re-open or comment if you would like to discuss it further.

@karmi
Copy link
Contributor

karmi commented Nov 21, 2019

Hi @geoffmore , I was wrong about Elasticsearch itself not supporting the bearer/token authentication — sorry about that.

There's a broader discussion happening in #106 (comment) now about custom HTTP headers, which is related to the bearer/token authentication feature.

@geoffmore
Copy link
Author

@karmi I don't know enough about custom HTTP headers to contribute anything meaningful to #106 , but I am following the conversation to see where I can contribute.

karmi added a commit that referenced this pull request Apr 28, 2020
    hdr := http.Header{}
      hdr.Set("Accept", "application/yaml")
      hdr.Set("Authorization", "Bearer 46ToAxZ2ZGZCaDhEVVNJQ0J1dUYzdGZxa1BB")

    es, err := elasticsearch.NewClient(
      elasticsearch.Config{
        Header: hdr,
      },
    )

    res, _ := es.Info()
    fmt.Println(res)

    # [200 OK] ---
    # name: "es1"
    # ...

Related:

* #136
* #84
* #106 (comment)
karmi added a commit that referenced this pull request Apr 28, 2020
    hdr := http.Header{}
      hdr.Set("Accept", "application/yaml")
      hdr.Set("Authorization", "Bearer 46ToAxZ2ZGZCaDhEVVNJQ0J1dUYzdGZxa1BB")

    es, err := elasticsearch.NewClient(
      elasticsearch.Config{
        Header: hdr,
      },
    )

    res, _ := es.Info()
    fmt.Println(res)

    # [200 OK] ---
    # name: "es1"
    # ...

Related:

* #136
* #84
* #106 (comment)

(cherry picked from commit 3f39d54)
karmi added a commit that referenced this pull request Apr 28, 2020
    hdr := http.Header{}
      hdr.Set("Accept", "application/yaml")
      hdr.Set("Authorization", "Bearer 46ToAxZ2ZGZCaDhEVVNJQ0J1dUYzdGZxa1BB")

    es, err := elasticsearch.NewClient(
      elasticsearch.Config{
        Header: hdr,
      },
    )

    res, _ := es.Info()
    fmt.Println(res)

    # [200 OK] ---
    # name: "es1"
    # ...

Related:

* #136
* #84
* #106 (comment)

(cherry picked from commit 3f39d54)
karmi added a commit that referenced this pull request Apr 28, 2020
    hdr := http.Header{}
      hdr.Set("Accept", "application/yaml")
      hdr.Set("Authorization", "Bearer 46ToAxZ2ZGZCaDhEVVNJQ0J1dUYzdGZxa1BB")

    es, err := elasticsearch.NewClient(
      elasticsearch.Config{
        Header: hdr,
      },
    )

    res, _ := es.Info()
    fmt.Println(res)

    # [200 OK] ---
    # name: "es1"
    # ...

Related:

* #136
* #84
* #106 (comment)

(cherry picked from commit 3f39d54)
@karmi
Copy link
Contributor

karmi commented Apr 28, 2020

Custom global HTTP request headers have been added in 3f39d54.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants