modified config+authorization
This commit is contained in:
parent
261cfb96c4
commit
5c33c5ff14
6 changed files with 103 additions and 71 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -12,7 +12,4 @@
|
|||
*.out
|
||||
|
||||
# Dependency directories (remove the comment below to include it)
|
||||
# vendor/
|
||||
|
||||
#run-script including environment-variable values for test instances
|
||||
run.ps1
|
||||
# vendor/
|
42
.vscode/launch.json
vendored
Normal file
42
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "weather-api",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceFolder}/main.go",
|
||||
"env": {
|
||||
"MONGO_HOST":"localhost:27017",
|
||||
"MONGO_DB":"weathersensors",
|
||||
"MONGO_COLLECTION":"data",
|
||||
"MONGO_USER":"root",
|
||||
"MONGO_PASSWORD":"rootPassXXX",
|
||||
|
||||
"INFLUX_HOST":"localhost",
|
||||
"INFLUX_TOKEN":"token",
|
||||
"INFLUX_ORG":"weather-org",
|
||||
"INFLUX_BUCKET":"weatherdata",
|
||||
|
||||
"MQTT_HOST":"localhost:1883",
|
||||
"MQTT_TOPIC":"sensor/#",
|
||||
"MQTT_USER":"mqtt",
|
||||
"MQTT_PASSWORD":"mqtt",
|
||||
"MQTT_PUBLISH_DELAY":"1000",
|
||||
"MQTT_ANONYMOUS":"false",
|
||||
|
||||
"ACCESS_CONTROL_ALLOW_ORIGIN_HEADER":"*",
|
||||
"USE_JWT_TOKEN_VALIDATION_URL":"false",
|
||||
"JWT_TOKEN_VALIDATION_URL":"localhost:5000",
|
||||
"USE_JWT_TOKEN_VALIDATION_SECRET":"false",
|
||||
"JWT_TOKEN_VALIDATION_SECRET":"token_Secret_value",
|
||||
|
||||
"ALLOW_UNREGISTERED_SENSORS":"true",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
14
README.md
14
README.md
|
@ -24,7 +24,7 @@ Key | Default-Wert | Auswirkung
|
|||
MONGO_HOST | localhost:27017 | Hostadresse mongodb
|
||||
MONGO_DB | weathersensors | DB-Namen mongodb
|
||||
MONGO_USER | admin | Username mongodb
|
||||
MONGO_PASS | admin | Passwort mongodb
|
||||
MONGO_PASSWORD | admin | Passwort mongodb
|
||||
MONGO_COLLECTION | sensors | mongodb-Collection, in der Wettersensoren gespeichert werden
|
||||
INFLUX_HOST | localhost:8086 | Hostadresse influxdb
|
||||
INFLUX_TOKEN | token | Token für influxDB
|
||||
|
@ -33,13 +33,13 @@ INFLUX_BUCKET | bucket_name | Bucket-Namen, in dem die Wetterdaten abgespeichert
|
|||
MQTT_HOST | localhost:1883 | Hostadresse MQTT-Broker
|
||||
MQTT_TOPIC | sensor/# | MQTT-Topic, in welchem nach Wetterdaten geschaut wird
|
||||
MQTT_USER | mqtt | Username für MQTT
|
||||
MQTT_PASS | mqtt | Passwort für MQTT
|
||||
MQTT_PASSWORD | mqtt | Passwort für MQTT
|
||||
MQTT_PUBLISH_DELAY | 1000 | Innerhalb dieser Zeitspanne wird ein Wetterdatensatz noch durch weiter eintreffende Werte ergänzt. Danach wird der Datensatz veröffentlicht (in Millisekunden)
|
||||
MQTT_ANONYMOUS | false | Anonyme Anmeldung am MQTT-Broker verwenden (ohne Username und Passwort)
|
||||
ACCESS_CONTROL_ALLOW_ORIGIN_HEADER | * | CORS-Header
|
||||
USE_JWT_TOKEN_VALIDATION_URL | false | Tokenvalidierung an einer URL
|
||||
JWT_TOKEN_VALIDATION_URL | localhost:5000 | URL für die JWT-Token Validierung
|
||||
USE_JWT_TOKEN_VALIDATION_SECRET | true | Tokenvalidierung mit der Angabe eines Secrets
|
||||
JWT_TOKEN_VALIDATION_SECRET | token_Secret_value | Secret um die Signatur des JWT-Tokens zu überprüfen
|
||||
ALLOW_UNREGISTERED_SENSORS | false | Wetterdaten nicht registrierter Sensoren erlauben
|
||||
|
||||
|
||||
## Applikation lokal ausführen
|
||||
|
||||
Eine lokal ausgeführte Test-Instanz der Wetter-API muss mit URLs, Tokens und ähnlichem über Umgebungsvariablen konfiguriert werden.
|
||||
Das PowerShell-Skript `run_default.ps1` ist eine Vorlage für den start einer eigenen Instanz, lediglich die Umgebungsvariablen müsssen hierzu angepasst werden. Am besten wird der Inhalt dieses Skriptes in ein weiteres Skript (z.B. `run.ps1`) kopiert. Dieses wird von Git ignoriert, geheime Zugangsdaten (z.B. zu MQTT Broker, InfluxDB) werden so nicht ins Git-Repository eingefügt.
|
||||
|
|
|
@ -24,10 +24,19 @@ var bearerTokenRegexPattern = "^(?i:Bearer\\s+)([A-Za-z0-9-_=]+\\.[A-Za-z0-9-_=]
|
|||
|
||||
var bearerTokenRegex *regexp.Regexp = regexp.MustCompile(bearerTokenRegexPattern)
|
||||
|
||||
type UserClaims struct {
|
||||
type User struct {
|
||||
Uid string `json:"uid"`
|
||||
Username string `json:"username"`
|
||||
Roles []string `json:"role"`
|
||||
}
|
||||
|
||||
type ValidationResponse struct {
|
||||
ValidationSuccessfull bool
|
||||
Identity User
|
||||
}
|
||||
|
||||
type UserClaims struct {
|
||||
User
|
||||
jwt.StandardClaims
|
||||
}
|
||||
|
||||
|
@ -74,7 +83,8 @@ func (api *weatherRestApi) handleRequests() *mux.Router {
|
|||
|
||||
//sensor specific stuff
|
||||
sensorRouter := router.PathPrefix("/{_dummy:(?i)sensor}").Subrouter()
|
||||
sensorRouter.Use(api.IsAuthorized)
|
||||
sensorRouter.Use(api.UseJwtTokenValidationSecret)
|
||||
sensorRouter.Use(api.UseJwtTokenValidationUrl)
|
||||
|
||||
sensorRouter.HandleFunc("/{id}/{_dummy:(?i)weather-data}", api.getWeatherDataHandler).Methods("GET")
|
||||
sensorRouter.HandleFunc("/{id}/{_dummy:(?i)weather-data}", api.addWeatherDataHandler).Methods("POST")
|
||||
|
@ -281,14 +291,13 @@ func (api *weatherRestApi) homePageHandler(w http.ResponseWriter, r *http.Reques
|
|||
fmt.Fprintf(w, "Welcome to the Weather API!")
|
||||
}
|
||||
|
||||
func (api *weatherRestApi) IsAuthorized(next http.Handler) http.Handler {
|
||||
func (api *weatherRestApi) UseJwtTokenValidationUrl(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !api.config.UseTokenAuthorization {
|
||||
if !api.config.UseJwtTokenValidationUrl {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, api.config.ValidateTokenUrl, &bytes.Buffer{})
|
||||
req, err := http.NewRequest(http.MethodGet, api.config.JwtTokenValidationUrl, &bytes.Buffer{})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
|
@ -302,18 +311,35 @@ func (api *weatherRestApi) IsAuthorized(next http.Handler) http.Handler {
|
|||
return
|
||||
}
|
||||
|
||||
claims, err := api.parseToken(r.Header)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
r.Header.Set(userIdHeader, claims.Uid)
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
next.ServeHTTP(w, r)
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
http.Error(w, resp.Status, resp.StatusCode)
|
||||
return
|
||||
}
|
||||
|
||||
http.Error(w, "", http.StatusUnauthorized)
|
||||
validation := new(ValidationResponse)
|
||||
err = json.NewDecoder(resp.Body).Decode(validation)
|
||||
if err != nil || !validation.ValidationSuccessfull {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
r.Header.Set(userIdHeader, validation.Identity.Uid)
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
func (api *weatherRestApi) UseJwtTokenValidationSecret(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if !api.config.UseJwtTokenValidationSecret {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
claims, err := api.parseToken(r.Header)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
r.Header.Set(userIdHeader, claims.Uid)
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -331,7 +357,7 @@ func (api *weatherRestApi) parseToken(header http.Header) (*UserClaims, error) {
|
|||
jwtFromHeader,
|
||||
claims,
|
||||
func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte(api.config.JwtTokenSecret), nil
|
||||
return []byte(api.config.JwtTokenValidationSecret), nil
|
||||
},
|
||||
)
|
||||
return claims, err
|
||||
|
|
|
@ -32,16 +32,18 @@ type MqttConfig struct {
|
|||
|
||||
type RestConfig struct {
|
||||
AccessControlAllowOriginHeader string
|
||||
UseTokenAuthorization bool
|
||||
ValidateTokenUrl string
|
||||
JwtTokenSecret string
|
||||
Insecure bool
|
||||
UseJwtTokenValidationUrl bool
|
||||
JwtTokenValidationUrl string
|
||||
UseJwtTokenValidationSecret bool
|
||||
JwtTokenValidationSecret string
|
||||
}
|
||||
|
||||
var MongoConfiguration = MongoConfig{
|
||||
Host: getEnv("MONGO_HOST", "localhost:27017"),
|
||||
Database: getEnv("MONGO_DB", "weathersensors"),
|
||||
Username: getEnv("MONGO_USER", "admin"),
|
||||
Password: getEnv("MONGO_PASS", "admin"),
|
||||
Password: getEnv("MONGO_PASSWORD", "admin"),
|
||||
Collection: getEnv("MONGO_COLLECTION", "sensors"),
|
||||
}
|
||||
|
||||
|
@ -56,16 +58,17 @@ var MqttConfiguration = MqttConfig{
|
|||
Host: getEnv("MQTT_HOST", "localhost:1883"),
|
||||
Topic: getEnv("MQTT_TOPIC", "sensor/#"),
|
||||
Username: getEnv("MQTT_USER", "mqtt"),
|
||||
Password: getEnv("MQTT_PASS", "mqtt"),
|
||||
Password: getEnv("MQTT_PASSWORD", "mqtt"),
|
||||
PublishDelay: getEnvDuration("MQTT_PUBLISH_DELAY", time.Second),
|
||||
AllowAnonymousAuthentication: getEnvBool("MQTT_ANONYMOUS", false),
|
||||
}
|
||||
|
||||
var RestConfiguration = RestConfig{
|
||||
AccessControlAllowOriginHeader: getEnv("ACCESS_CONTROL_ALLOW_ORIGIN_HEADER", "*"),
|
||||
UseTokenAuthorization: getEnvBool("USE_TOKEN_AUTHORIZATION", false),
|
||||
ValidateTokenUrl: getEnv("JWT_TOKEN_VALIDATION_URL", "https://api.swablab.de/ldap/validateToken"),
|
||||
JwtTokenSecret: getEnv("JWT_TOKEN_SECRET", "my_token_string"),
|
||||
UseJwtTokenValidationUrl: getEnvBool("USE_JWT_TOKEN_VALIDATION_URL", false),
|
||||
JwtTokenValidationUrl: getEnv("JWT_TOKEN_VALIDATION_URL", "localhost:5000"),
|
||||
UseJwtTokenValidationSecret: getEnvBool("USE_JWT_TOKEN_VALIDATION_SECRET", true),
|
||||
JwtTokenValidationSecret: getEnv("JWT_TOKEN_VALIDATION_SECRET", "my_token_string"),
|
||||
}
|
||||
|
||||
var AllowUnregisteredSensors = getEnvBool("ALLOW_UNREGISTERED_SENSORS", false)
|
||||
|
@ -90,16 +93,6 @@ func getEnvBool(key string, fallback bool) bool {
|
|||
return fallback
|
||||
}
|
||||
|
||||
func getEnvInt(key string, fallback int64) int64 {
|
||||
if value, ok := os.LookupEnv(key); ok {
|
||||
if iValue, err := strconv.ParseInt(value, 10, 64); err == nil {
|
||||
return iValue
|
||||
}
|
||||
}
|
||||
|
||||
return fallback
|
||||
}
|
||||
|
||||
func getEnvDuration(key string, fallback time.Duration) time.Duration {
|
||||
if value, ok := os.LookupEnv(key); ok {
|
||||
if iValue, err := strconv.ParseInt(value, 10, 64); err == nil {
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
#build the application
|
||||
go build main.go
|
||||
|
||||
#set environment variables for weather-api configuration
|
||||
Set-Item -Path "Env:INFLUX_HOST" -Value "localhost:8086"
|
||||
Set-Item -Path "Env:INFLUX_TOKEN" -Value "token"
|
||||
Set-Item -Path "Env:INFLUX_ORG" -Value "org-name"
|
||||
Set-Item -Path "Env:INFLUX_BUCKET" -Value "bucket-name"
|
||||
|
||||
Set-Item -Path "Env:MQTT_HOST" -Value "localhost:1883"
|
||||
Set-Item -Path "Env:MQTT_TOPIC" -Value "sensor/#"
|
||||
Set-Item -Path "Env:MQTT_USER" -Value "mqtt"
|
||||
Set-Item -Path "Env:MQTT_PASS" -Value "mqtt"
|
||||
Set-Item -Path "Env:MQTT_PUBLISH_DELAY" -Value "1000"
|
||||
Set-Item -Path "Env:MQTT_ANONYMOUS" -Value "false"
|
||||
|
||||
Set-Item -Path "Env:MONGO_HOST" -Value "localhost:27017"
|
||||
Set-Item -Path "Env:MONGO_DB" -Value "weathersensors"
|
||||
Set-Item -Path "Env:MONGO_COLLECTION" -Value "sensors"
|
||||
Set-Item -Path "Env:MONGO_USER" -Value "admin"
|
||||
Set-Item -Path "Env:MONGO_PASS" -Value "admin"
|
||||
|
||||
Set-Item -Path "Env:ALLOW_UNREGISTERED_SENSORS" -Value "false"
|
||||
|
||||
#start application
|
||||
Start-Process "main.exe" -Wait -NoNewWindow
|
Loading…
Add table
Reference in a new issue