mirror of
https://github.com/gogrlx/nats-server.git
synced 2026-04-02 03:38:42 -07:00
[ADDED] Support for token in configuration file
So far, it was only possible to use token from the command line. Resolves #464
This commit is contained in:
10
README.md
10
README.md
@@ -394,6 +394,16 @@ authorization {
|
||||
}
|
||||
```
|
||||
|
||||
Or, if you chose to use a token:
|
||||
|
||||
```
|
||||
authorization {
|
||||
# You can generate the token using /util/mkpassword.go
|
||||
token: $2a$11$pBwUBpza8vdJ7tWZcP5GRO13qRgh4dwNn8g67k5i/41yIKBp.sHke
|
||||
timeout: 1
|
||||
}
|
||||
```
|
||||
|
||||
**Multi-user authentication**
|
||||
|
||||
You can enable multi-user authentication using a NATS server configuration file that defines user credentials (`user` and `password`), and optionally `permissions`, for two or more users. Multi-user authentication leverages [variables](#variables).
|
||||
|
||||
@@ -88,8 +88,9 @@ type Options struct {
|
||||
// Configuration file authorization section.
|
||||
type authorization struct {
|
||||
// Singles
|
||||
user string
|
||||
pass string
|
||||
user string
|
||||
pass string
|
||||
token string
|
||||
// Multiple Users
|
||||
users []*User
|
||||
timeout float64
|
||||
@@ -174,12 +175,19 @@ func ProcessConfigFile(configFile string) (*Options, error) {
|
||||
}
|
||||
opts.Username = auth.user
|
||||
opts.Password = auth.pass
|
||||
opts.Authorization = auth.token
|
||||
if (auth.user != "" || auth.pass != "") && auth.token != "" {
|
||||
return nil, fmt.Errorf("Cannot have a user/pass and token")
|
||||
}
|
||||
opts.AuthTimeout = auth.timeout
|
||||
// Check for multiple users defined
|
||||
if auth.users != nil {
|
||||
if auth.user != "" {
|
||||
return nil, fmt.Errorf("Can not have a single user/pass and a users array")
|
||||
}
|
||||
if auth.token != "" {
|
||||
return nil, fmt.Errorf("Can not have a token and a users array")
|
||||
}
|
||||
opts.Users = auth.users
|
||||
}
|
||||
case "http":
|
||||
@@ -340,6 +348,8 @@ func parseAuthorization(am map[string]interface{}) (*authorization, error) {
|
||||
auth.user = mv.(string)
|
||||
case "pass", "password":
|
||||
auth.pass = mv.(string)
|
||||
case "token":
|
||||
auth.token = mv.(string)
|
||||
case "timeout":
|
||||
at := float64(1)
|
||||
switch mv.(type) {
|
||||
|
||||
@@ -4,8 +4,11 @@ package server
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
@@ -605,3 +608,46 @@ func TestAuthorizationConfig(t *testing.T) {
|
||||
t.Fatalf("Expected Susan's subscribe permissions to be 'PUBLIC.>', got %q\n", subPerm)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenWithUserPass(t *testing.T) {
|
||||
confFileName := "test.conf"
|
||||
defer os.Remove(confFileName)
|
||||
content := `
|
||||
authorization={
|
||||
user: user
|
||||
pass: password
|
||||
token: $2a$11$whatever
|
||||
}`
|
||||
if err := ioutil.WriteFile(confFileName, []byte(content), 0666); err != nil {
|
||||
t.Fatalf("Error writing config file: %v", err)
|
||||
}
|
||||
_, err := ProcessConfigFile(confFileName)
|
||||
if err == nil {
|
||||
t.Fatal("Expected error, got none")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "token") {
|
||||
t.Fatalf("Expected error related to token, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTokenWithUsers(t *testing.T) {
|
||||
confFileName := "test.conf"
|
||||
defer os.Remove(confFileName)
|
||||
content := `
|
||||
authorization={
|
||||
token: $2a$11$whatever
|
||||
users: [
|
||||
{user: test, password: test}
|
||||
]
|
||||
}`
|
||||
if err := ioutil.WriteFile(confFileName, []byte(content), 0666); err != nil {
|
||||
t.Fatalf("Error writing config file: %v", err)
|
||||
}
|
||||
_, err := ProcessConfigFile(confFileName)
|
||||
if err == nil {
|
||||
t.Fatal("Expected error, got none")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "token") {
|
||||
t.Fatalf("Expected error related to token, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ package test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/nats-io/go-nats"
|
||||
@@ -48,3 +50,32 @@ func TestMultipleUserAuth(t *testing.T) {
|
||||
}
|
||||
defer nc.Close()
|
||||
}
|
||||
|
||||
// Resolves to "test"
|
||||
const testToken = "$2a$05$3sSWEVA1eMCbV0hWavDjXOx.ClBjI6u1CuUdLqf22cbJjXsnzz8/."
|
||||
|
||||
func TestTokenInConfig(t *testing.T) {
|
||||
confFileName := "test.conf"
|
||||
defer os.Remove(confFileName)
|
||||
content := `
|
||||
listen: 127.0.0.1:4567
|
||||
authorization={
|
||||
token: ` + testToken + `
|
||||
timeout: 5
|
||||
}`
|
||||
if err := ioutil.WriteFile(confFileName, []byte(content), 0666); err != nil {
|
||||
t.Fatalf("Error writing config file: %v", err)
|
||||
}
|
||||
s, opts := RunServerWithConfig(confFileName)
|
||||
defer s.Shutdown()
|
||||
|
||||
url := fmt.Sprintf("nats://test@%s:%d/", opts.Host, opts.Port)
|
||||
nc, err := nats.Connect(url)
|
||||
if err != nil {
|
||||
t.Fatalf("Expected a successful connect, got %v\n", err)
|
||||
}
|
||||
defer nc.Close()
|
||||
if !nc.AuthRequired() {
|
||||
t.Fatal("Expected auth to be required for the server")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user