Skip to content

Commit

Permalink
Support basic authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
fisuda committed Jul 4, 2021
1 parent 0e30b11 commit db84352
Show file tree
Hide file tree
Showing 15 changed files with 376 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NGSI Go v0.8.4-next

- Hardening: Support basic authentication (#162)
- Update: Refactoring token manager (#161)
- Fix: Print stack messages correctly (#160)
- Hardening: Add WireCloud command (#159)
Expand Down
15 changes: 15 additions & 0 deletions docs/management/broker.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,20 @@ ngsi broker add \
--service smartcity
```

#### Example 6

Orion with Basic authentication

```console
ngsi broker add \
--host orion-with-basic-auth \
--ngsiType v2 \
--brokerHost http://localhost:1026/ \
--idmType basic \
--username fiware \
--password 1234
```

### NGSI type

Specify `v2` to `--ngsiType` when you add an alias for FIWARE Orion Context Broker.
Expand All @@ -206,6 +220,7 @@ Specify `v2` to `--ngsiType` when you add an alias for FIWARE Orion Context Brok

| idmType | Required parameters | Description |
| -------------------------------------------------------------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------- |
| basic | username, password | Basic authentication |
| password | idmHost, username, password, clientId, clientSecret | This type is for Password Credentials of Keycloak, WSO2, Apinf, and Stellio) |
| [keyrock](https://fiware-idm.readthedocs.io/) | idmHost, username, password, clientId, clientSecret | This type is for Password Credentials of Keyrock |
| [KeyrockTokenProvider](https://github.com/FIWARE-Ops/KeyrockTokenProvider) | idmHost, username, password | It provides auth token from Keyrock |
Expand Down
53 changes: 53 additions & 0 deletions e2e/cases/3000_management/0104_broker_add.test
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,59 @@ ngsi broker delete --host tenant
```
```

#
# 0051 Add broker (Basic authentication)
#
ngsi broker add --host orion-with-basic-auth --ngsiType v2 --brokerHost http://localhost:1026/ \
--idmType basic \
--username fiware \
--password 1234

```
```

#
# 0052 Get broker
#
ngsi broker get --host orion-with-basic-auth

```
brokerHost http://localhost:1026/
ngsiType v2
IdmType basic
Username fiware
Password ****
```

#
# 0053 Update broker
#
ngsi broker update --host orion-with-basic-auth --username orion

```
```

#
# 0054 Get broker
#
ngsi broker get --host orion-with-basic-auth --clearText

```
brokerHost http://localhost:1026/
ngsiType v2
IdmType basic
Username orion
Password 1234
```

#
# 0055 Delete broker
#
ngsi broker delete --host orion-with-basic-auth

```
```

#
# 0100 brokersAdd002 Required host not found
#
Expand Down
52 changes: 52 additions & 0 deletions extras/basic_authentication/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Access a broker with Basic authentication

This documentation explains how to access an Orion Context Broker that the endpoints of NGSI API
are protected by Basic Authentication.

## Add user

Add username and password to the htpasswd file.

```
NAME=fiware PASS='1234'; echo $NAME:`openssl passwd -6 $PASS` >> htpasswd
```

## Start up

Start up an Orion context broker.

```
docker-compose up -d
```

You can see three containers.

```
Name Command State Ports
--------------------------------------------------------------------------------------------------------
basic_authentication_mongo_1 docker-entrypoint.sh --noj ... Up 27017/tcp
basic_authentication_nginx_1 /docker-entrypoint.sh ngin ... Up 0.0.0.0:80->80/tcp,:::80->80/tcp
basic_authentication_orion_1 /usr/bin/contextBroker -fg ... Up 1026/tcp
```

## Add the broker

Add the broker to NGSI Go configuration.

```
ngsi broker add \
--host orion-with-basic-auth \
--ngsiType v2 \
--brokerHost http://localhost/ \
--idmType basic \
--username fiware \
--password 1234
```

## Access the broker

The following command allows you to access the broker with Basic authentication.

```
ngsi version --host orion-with-basic-auth
```
22 changes: 22 additions & 0 deletions extras/basic_authentication/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
version: "3"

services:
nginx:
image: nginx:latest
ports:
- 80:80
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./htpasswd:/etc/nginx/.htpasswd:ro
depends_on:
- orion

orion:
image: fiware/orion:3.1.0
depends_on:
- mongo
command: -dbhost mongo

mongo:
image: mongo:4.4
command: --nojournal
Empty file.
24 changes: 24 additions & 0 deletions extras/basic_authentication/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
user nginx;
worker_processes 1;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;

server {
listen 80;

location / {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;

proxy_pass http://orion:1026;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
5 changes: 4 additions & 1 deletion internal/ngsicmd/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,15 @@ func tokenCommand(c *cli.Context) error {
if c.Bool("verbose") || c.Bool("pretty") {
var b []byte
switch token.Type {
default: // ngsilib.CKeyrock, ngsilib.CTokenproxy, ngsilib.CKeyrocktokenprovider:
default: // ngsilib.CKeyrock, ngsilib.CTokenproxy, ngsilib.CKeyrocktokenprovider
token.Oauth.ExpiresIn = time
b, err = ngsilib.JSONMarshal(token.Oauth)
if err != nil {
return &ngsiCmdError{funcName, 4, err.Error(), err}
}
case ngsilib.CBasic:
fmt.Fprintln(ngsi.StdWriter, "no information available")
return nil
case ngsilib.CThinkingCities:
b, err = ngsilib.JSONMarshal(token.Keystone)
if err != nil {
Expand Down
56 changes: 44 additions & 12 deletions internal/ngsicmd/token_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import (
"github.com/urfave/cli/v2"
)

func TestVersionTokenCommand(t *testing.T) {
func TestTokenCommand(t *testing.T) {
ngsi, set, app, buf := setupTest()

conf := `{
Expand Down Expand Up @@ -74,7 +74,7 @@ func TestVersionTokenCommand(t *testing.T) {
}
}

func TestVersionTokenCommandJSON(t *testing.T) {
func TestTokenCommandJSON(t *testing.T) {
ngsi, set, app, buf := setupTest()

conf := `{
Expand Down Expand Up @@ -112,7 +112,7 @@ func TestVersionTokenCommandJSON(t *testing.T) {
}
}

func TestVersionTokenCommandJSONPretty(t *testing.T) {
func TestTokenCommandJSONPretty(t *testing.T) {
ngsi, set, app, buf := setupTest()

conf := `{
Expand Down Expand Up @@ -150,7 +150,7 @@ func TestVersionTokenCommandJSONPretty(t *testing.T) {
}
}

func TestVersionTokenCommandJSONExpiresZero(t *testing.T) {
func TestTokenCommandJSONExpiresZero(t *testing.T) {
ngsi, set, app, buf := setupTest()

conf := `{
Expand Down Expand Up @@ -190,7 +190,7 @@ func TestVersionTokenCommandJSONExpiresZero(t *testing.T) {

}

func TestVersionTokenCommandExpires(t *testing.T) {
func TestTokenCommandExpires(t *testing.T) {
ngsi, set, app, buf := setupTest()

conf := `{
Expand Down Expand Up @@ -229,7 +229,7 @@ func TestVersionTokenCommandExpires(t *testing.T) {
}
}

func TestVersionTokenCommandExpiresZero(t *testing.T) {
func TestTokenCommandExpiresZero(t *testing.T) {
ngsi, set, app, buf := setupTest()

conf := `{
Expand Down Expand Up @@ -268,7 +268,7 @@ func TestVersionTokenCommandExpiresZero(t *testing.T) {
}
}

func TestVersionTokenCommandKeyrock(t *testing.T) {
func TestTokenCommandKeyrock(t *testing.T) {
ngsi, set, app, buf := setupTest()

conf := `{
Expand Down Expand Up @@ -316,6 +316,38 @@ func TestVersionTokenCommandKeyrock(t *testing.T) {
}
}

func TestTokenCommandBasic(t *testing.T) {
ngsi, set, app, buf := setupTest()

conf := `{
"version": "1",
"servers": {
"orion": {
"serverHost": "http://orion",
"ngsiType": "v2",
"idmType": "basic",
"username": "testuser",
"password": "1234"
}
}
}`
ngsi.FileReader = &MockFileLib{ReadFileData: []byte(conf)}

setupFlagString(set, "host")
set.Bool("verbose", false, "doc")

c := cli.NewContext(app, set, nil)
_ = set.Parse([]string{"--host=orion", "--verbose"})

err := tokenCommand(c)

if assert.NoError(t, err) {
actual := buf.String()
expected := "no information available\n"
assert.Equal(t, expected, actual)
}
}

// initCmd() Error: no host
func TestTokenCommandErrorInitCmd(t *testing.T) {
_, set, app, _ := setupTest()
Expand Down Expand Up @@ -353,7 +385,7 @@ func TestTokenCommandErrorNewClient(t *testing.T) {
}
}

func TestVersionTokenCommandErrorHostNotFound(t *testing.T) {
func TestTokenCommandErrorHostNotFound(t *testing.T) {
ngsi, set, app, _ := setupTest()

reqRes := MockHTTPReqRes{}
Expand All @@ -377,7 +409,7 @@ func TestVersionTokenCommandErrorHostNotFound(t *testing.T) {
}
}

func TestVersionTokenCommandErrorOAuthJSON(t *testing.T) {
func TestTokenCommandErrorOAuthJSON(t *testing.T) {
ngsi, set, app, _ := setupTest()

conf := `{
Expand Down Expand Up @@ -418,7 +450,7 @@ func TestVersionTokenCommandErrorOAuthJSON(t *testing.T) {
}
}

func TestVersionTokenCommandErrorThinkingCitesJSON(t *testing.T) {
func TestTokenCommandErrorThinkingCitesJSON(t *testing.T) {
ngsi, set, app, _ := setupTest()

conf := `{
Expand Down Expand Up @@ -459,7 +491,7 @@ func TestVersionTokenCommandErrorThinkingCitesJSON(t *testing.T) {
}
}

func TestVersionTokenCommandErrorKeyrock(t *testing.T) {
func TestTokenCommandErrorKeyrock(t *testing.T) {
ngsi, set, app, _ := setupTest()

conf := `{
Expand Down Expand Up @@ -499,7 +531,7 @@ func TestVersionTokenCommandErrorKeyrock(t *testing.T) {
}
}

func TestVersionTokenCommandErrorJSONPretty(t *testing.T) {
func TestTokenCommandErrorJSONPretty(t *testing.T) {
ngsi, set, app, _ := setupTest()

conf := `{
Expand Down
2 changes: 2 additions & 0 deletions internal/ngsilib/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ func (client *Client) InitHeader() error {
if client.Server.ServerType == "keyrock" {
client.Headers["X-Auth-Token"] = client.Token
client.Headers["X-Subject-token"] = client.Token
} else if client.Server.IdmType == CBasic {
client.Headers["Authorization"] = "Basic " + client.Token
} else if client.XAuthToken || client.Server.IdmType == CThinkingCities {
client.Headers["X-Auth-Token"] = client.Token
} else {
Expand Down
9 changes: 9 additions & 0 deletions internal/ngsilib/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ func TestInitHeaderKeyrock(t *testing.T) {
assert.NoError(t, err)
}

func TestInitHeaderBasic(t *testing.T) {
client := &Client{URL: &url.URL{}, Headers: map[string]string{}, Token: "b7308719683033900d37384e723c1660"}
client.Server = &Server{ServerType: "broker", IdmType: CBasic}

err := client.InitHeader()

assert.NoError(t, err)
}

func TestInitHeaderXAuthToken(t *testing.T) {
client := &Client{URL: &url.URL{}, Headers: map[string]string{}}
client.Server = &Server{ServerType: "broker"}
Expand Down
Loading

0 comments on commit db84352

Please sign in to comment.