Allow to specify a function that supply a token (#130)

* Allow to specify a function that supply a token

* Fixed godocs

* Fixed else block
diff --git a/pulsar/client.go b/pulsar/client.go
index 98a2189..31257ed 100644
--- a/pulsar/client.go
+++ b/pulsar/client.go
@@ -39,6 +39,14 @@
 	return auth.NewAuthenticationToken(token)
 }
 
+// NewAuthenticationTokenFromSupplier returns a token auth provider that
+// gets the token data from a user supplied function. The function is
+// invoked each time the client library needs to use a token in talking
+// with Pulsar brokers
+func NewAuthenticationTokenFromSupplier(tokenSupplier func() (string, error)) Authentication {
+	return auth.NewAuthenticationTokenFromSupplier(tokenSupplier)
+}
+
 // Create new Authentication provider with specified auth token from a file
 func NewAuthenticationTokenFromFile(tokenFilePath string) Authentication {
 	return auth.NewAuthenticationTokenFromFile(tokenFilePath)
diff --git a/pulsar/client_impl_test.go b/pulsar/client_impl_test.go
index d9849bd..841069a 100644
--- a/pulsar/client_impl_test.go
+++ b/pulsar/client_impl_test.go
@@ -174,6 +174,30 @@
 	client.Close()
 }
 
+func TestTokenAuthWithSupplier(t *testing.T) {
+	client, err := NewClient(ClientOptions{
+		URL:            serviceURL,
+		Authentication: NewAuthenticationTokenFromSupplier(func() (s string, err error) {
+			token, err := ioutil.ReadFile(tokenFilePath)
+			if err != nil {
+				return "", err
+			}
+
+			return string(token), nil
+		}),
+	})
+	assert.NoError(t, err)
+
+	producer, err := client.CreateProducer(ProducerOptions{
+		Topic: newAuthTopicName(),
+	})
+
+	assert.NoError(t, err)
+	assert.NotNil(t, producer)
+
+	client.Close()
+}
+
 func TestTokenAuthFromFile(t *testing.T) {
 	client, err := NewClient(ClientOptions{
 		URL:            serviceURL,
diff --git a/pulsar/internal/auth/token.go b/pulsar/internal/auth/token.go
index c89eeaf..e6a6d97 100644
--- a/pulsar/internal/auth/token.go
+++ b/pulsar/internal/auth/token.go
@@ -40,7 +40,8 @@
 	}
 }
 
-// NewAuthenticationToken return a interface of Provider with a string token.
+// NewAuthenticationToken returns a token auth provider that will use the specified token to
+// talk with Pulsar brokers
 func NewAuthenticationToken(token string) Provider {
 	return &tokenAuthProvider{
 		tokenSupplier: func() (string, error) {
@@ -52,6 +53,15 @@
 	}
 }
 
+// NewAuthenticationTokenFromSupplier returns a token auth provider that get
+// the token data from a user supplied function. The function is invoked each
+// time the client library needs to use a token in talking with Pulsar brokers
+func NewAuthenticationTokenFromSupplier(tokenSupplier func() (string, error)) Provider {
+	return &tokenAuthProvider{
+		tokenSupplier: tokenSupplier,
+	}
+}
+
 // NewAuthenticationTokenFromFile return a interface of a Provider with a string token file path.
 func NewAuthenticationTokenFromFile(tokenFilePath string) Provider {
 	return &tokenAuthProvider{