You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by jv...@apache.org on 2017/03/11 18:09:54 UTC

[4/5] incubator-trafficcontrol git commit: update auth service to authenticate user against tm_users. add user's capabilities to jwt claims. capabilities are currently hard coded because role tables are not ready yet. webfront authorize user according to

update auth service to authenticate user against tm_users. add user's capabilities to jwt claims. capabilities are currently hard coded because role tables are not ready yet. webfront authorize user according to capabilities. jwt signing secret is passed to both services on command line


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/610f69c6
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/610f69c6
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/610f69c6

Branch: refs/heads/master
Commit: 610f69c6c730fd5b27c5b31ca74d44ca12cf6c9b
Parents: c6221c2
Author: Amir Yeshurun <am...@qwilt.com>
Authored: Sun Feb 26 23:29:40 2017 +0200
Committer: Jan van Doorn <ja...@cable.comcast.com>
Committed: Sat Mar 11 11:06:09 2017 -0700

----------------------------------------------------------------------
 traffic_ops/experimental/auth/README.md         |   9 ++
 traffic_ops/experimental/auth/auth.config       |  14 +-
 traffic_ops/experimental/auth/auth.go           | 115 +++++++++-------
 traffic_ops/experimental/webfront/README.md     | 132 ++++++-------------
 traffic_ops/experimental/webfront/rules.json    |  58 ++++----
 .../experimental/webfront/webfront.config       |   8 +-
 traffic_ops/experimental/webfront/webfront.go   |  35 ++---
 7 files changed, 181 insertions(+), 190 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/610f69c6/traffic_ops/experimental/auth/README.md
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/auth/README.md b/traffic_ops/experimental/auth/README.md
new file mode 100644
index 0000000..1e86579
--- /dev/null
+++ b/traffic_ops/experimental/auth/README.md
@@ -0,0 +1,9 @@
+
+A simple authentication server written in go that authenticates user agains the `tm_user` table and returns a jwt representing the user, incl. its API access capabilities, derived from the user's role.
+
+* To run:
+`go run auth.go auth.config my-secret`
+`secret` is used for jwt signing
+
+* To login:
+`curl --insecure -X POST -Lkvs --header "Content-Type:application/json" https://localhost:9004/login -d'{"username":"username", "password":"password"}'`

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/610f69c6/traffic_ops/experimental/auth/auth.config
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/auth/auth.config b/traffic_ops/experimental/auth/auth.config
index 642923e..2c4dfa5 100644
--- a/traffic_ops/experimental/auth/auth.config
+++ b/traffic_ops/experimental/auth/auth.config
@@ -1,8 +1,8 @@
 {
-	"dbName":"amiry",
-	"dbUser":"amiry",
-	"dbPassword":"blabla",
-	"dbServer":"localhost",
-	"dbPort":5432,
-	"listenerPort":"8080"
-}
+	"db-name":     "to_development",
+	"db-user":     "username",
+	"db-password": "password",
+	"db-server":   "localhost",
+	"db-port":     5432,
+	"listen-port": 9004
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/610f69c6/traffic_ops/experimental/auth/auth.go
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/auth/auth.go b/traffic_ops/experimental/auth/auth.go
index 937124f..0cedfef 100644
--- a/traffic_ops/experimental/auth/auth.go
+++ b/traffic_ops/experimental/auth/auth.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"crypto/sha1"
 	"encoding/json"
 	"fmt"
 	jwt "github.com/dgrijalva/jwt-go"
@@ -11,24 +12,28 @@ import (
 	"net/http"
 	"os"
 	"path"
+	"strconv"
 	"time"
 )
 
 // Config holds the configuration of the server.
 type Config struct {
-	DbName       string `json:"dbName"`
-	DbUser       string `json:"dbUser"`
-	DbPassword   string `json:"dbPassword"`
-	DbServer     string `json:"dbServer,omitempty"`
-	DbPort       uint   `json:"dbPort,omitempty"`
-	ListenerPort string `json:"listenerPort"`
+	DbName      string `json:"db-name"`
+	DbUser      string `json:"db-user"`
+	DbPassword  string `json:"db-password"`
+	DbServer    string `json:"db-server"`
+	DbPort      uint   `json:"db-port"`
+	ListenPort  uint   `json:"listen-port"`
 }
 
-type User struct {
-	Username  string `db:"username" json:"username"`
-	FirstName string `db:"first_name" json:"firstName,omitempty"`
-	LastName  string `db:"last_name" json:"lastName,omitempty"`
-	Password  string `db:"password" json:"password"`
+type Login struct {
+	Username    string `json:"username"`
+	Password    string `json:"password"`
+}
+
+type TmUser struct {
+	Role        uint   `db:"role"`
+	Password    string `db:"local_passwd"`
 }
 
 type Claims struct {
@@ -42,30 +47,29 @@ type TokenResponse struct {
 
 var db *sqlx.DB // global and simple
 
+var Logger *log.Logger
+
 func printUsage() {
 	exampleConfig := `{
-	"dbName":"my-db",
-	"dbUser":"my-user",
-	"dbPassword":"secret",
-	"dbServer":"localhost",
-	"dbPort":5432,
-	"listenerPort":"8080"
+	"db_name":     "to_development",
+	"db_user":     "username",
+	"db_password": "password",
+	"db_server":   "localhost",
+	"db_port":     5432,
+	"listen_port": 9004
 }`
-	Logger.Println("Usage: " + path.Base(os.Args[0]) + " configfile")
-	Logger.Println("")
-	Logger.Println("Example config file:")
-	Logger.Println(exampleConfig)
+	fmt.Println("Usage: " + path.Base(os.Args[0]) + " config-file secret")
+	fmt.Println("")
+	fmt.Println("Example config file:")
+	fmt.Println(exampleConfig)
 }
 
-var Logger *log.Logger
-
 func main() {
-	if len(os.Args) < 2 {
+	if len(os.Args) < 3 {
 		printUsage()
 		return
 	}
 
-	// log.SetOutput(os.Stdout)
 	Logger = log.New(os.Stdout, " ", log.Ldate|log.Ltime|log.Lshortfile)
 
 	file, err := os.Open(os.Args[1])
@@ -73,6 +77,7 @@ func main() {
 		Logger.Println("Error opening config file:", err)
 		return
 	}
+
 	decoder := json.NewDecoder(file)
 	config := Config{}
 	err = decoder.Decode(&config)
@@ -87,15 +92,18 @@ func main() {
 		return
 	}
 
-	http.HandleFunc("/", handler)
+	http.HandleFunc("/login", handler)
+	
 	if _, err := os.Stat("server.pem"); os.IsNotExist(err) {
 		Logger.Fatal("server.pem file not found")
 	}
+
 	if _, err := os.Stat("server.key"); os.IsNotExist(err) {
 		Logger.Fatal("server.key file not found")
 	}
-	Logger.Printf("Starting server on port " + config.ListenerPort + "...")
-	Logger.Fatal(http.ListenAndServeTLS(":"+config.ListenerPort, "server.pem", "server.key", nil))
+
+	Logger.Printf("Starting server on port %d...", config.ListenPort)
+	Logger.Fatal(http.ListenAndServeTLS(":" + strconv.Itoa(int(config.ListenPort)), "server.pem", "server.key", nil))
 }
 
 func InitializeDatabase(username, password, dbname, server string, port uint) (*sqlx.DB, error) {
@@ -114,59 +122,78 @@ func handler(w http.ResponseWriter, r *http.Request) {
 	Logger.Println(r.Method, r.URL.Scheme, r.Host, r.URL.RequestURI())
 
 	if r.Method == "POST" {
-		var u User
-		userlist := []User{}
+		var login Login
+		tmUserlist := []TmUser{}
 		body, err := ioutil.ReadAll(r.Body)
-		log.Println(string(body))
 		if err != nil {
 			Logger.Println("Error reading body: ", err.Error())
 			http.Error(w, "Error reading body: "+err.Error(), http.StatusBadRequest)
 			return
 		}
-		err = json.Unmarshal(body, &u)
+		
+		err = json.Unmarshal(body, &login)
 		if err != nil {
-			Logger.Println("Error unmarshalling JSON: ", err.Error())
+			Logger.Println("Invalid JSON: ", err.Error())
 			http.Error(w, "Invalid JSON: "+err.Error(), http.StatusBadRequest)
 			return
 		}
-		stmt, err := db.PrepareNamed("SELECT * FROM users WHERE username=:username")
-		err = stmt.Select(&userlist, u)
+		
+		stmt, err := db.PrepareNamed("SELECT role,local_passwd FROM tm_user WHERE username=:username")
 		if err != nil {
-			Logger.Println(err.Error())
+			Logger.Println("Database error: ", err.Error())
+			http.Error(w, "Database error: "+err.Error(), http.StatusInternalServerError)
+			return
+		}
+
+		err = stmt.Select(&tmUserlist, login)
+		if err != nil {
+			Logger.Println("Database error: ", err.Error())
 			http.Error(w, "Database error: "+err.Error(), http.StatusInternalServerError)
 			return
 		}
-		if len(userlist) == 0 || userlist[0].Password != u.Password {
-			http.Error(w, "Invalid username/password ", http.StatusUnauthorized)
+
+    	hasher := sha1.New()
+    	hasher.Write([]byte(login.Password))
+    	hashedPassword := fmt.Sprintf("%x", hasher.Sum(nil))
+
+		if len(tmUserlist) == 0 || tmUserlist[0].Password != string(hashedPassword) {
+			Logger.Printf("Invalid username/password, username %s", login.Username)
+			http.Error(w, "Invalid username/password", http.StatusUnauthorized)
 			return
 		}
 
+		Logger.Printf("User %s authenticated", login.Username)
+
 		claims := Claims {
-	        []string{"read-a", "write-a", "read-b"}, // TODO(amiry) - Read from DB
+	        []string{"read-ds", "write-ds", "read-cg"},	// TODO(amiry) - Adding hardcoded capabilities as a POC. 
+	        											// Need to read from TO role tables when tables are ready
 	        jwt.StandardClaims {
-	        	Subject: u.Username,
-	            ExpiresAt: time.Now().Add(time.Hour * 24).Unix(), // TODO(amiry) - Use shorter expiration
+	        	Subject: login.Username,
+	            ExpiresAt: time.Now().Add(time.Hour * 24).Unix(),	// TODO(amiry) - We will need to use shorter expiration, 
+	            													// and use refresh tokens to extend access
 	        },
 	    }
 
 		token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
 
-		tokenString, err := token.SignedString([]byte("CAmeRAFiveSevenNineNine")) // TODO(amiry) - Where to keep secret?
+		tokenString, err := token.SignedString([]byte(os.Args[2]))
 		if err != nil {
 			Logger.Println(err.Error())
 			http.Error(w, err.Error(), http.StatusInternalServerError)
 			return
 		}
+
 		js, err := json.Marshal(TokenResponse{Token: tokenString})
 		if err != nil {
 			Logger.Println(err.Error())
 			http.Error(w, err.Error(), http.StatusInternalServerError)
 			return
 		}
-		// w.WriteHeader(http.StatusOK)
+
 		w.Header().Set("Content-Type", "application/json")
 		w.Write(js)
 		return
 	}
+
 	http.Error(w, r.Method+" "+r.URL.Path+" not valid for this microservice", http.StatusNotFound)
-}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/610f69c6/traffic_ops/experimental/webfront/README.md
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/webfront/README.md b/traffic_ops/experimental/webfront/README.md
index 041a219..576f86e 100644
--- a/traffic_ops/experimental/webfront/README.md
+++ b/traffic_ops/experimental/webfront/README.md
@@ -1,98 +1,52 @@
-This application - webfront is a reverse proxy written in go that can front any number of microservices. It uses a rules file to map from requested host/path to microservice host/port/path.  Example rule file:
-
-   
-    [
-		{"Host": "local.com", "Path" : "/8001", "Forward": "localhost:8001"},
-		{"Host": "local.com", "Path" : "/8002", "Forward": "localhost:8002"},
-		{"Host": "local.com", "Path" : "/8003", "Forward": "localhost:8003"},
-		{"Host": "local.com", "Path" : "/8004", "Forward": "localhost:8004"},
-		{"Host": "local.com", "Path" : "/8005", "Forward": "localhost:8005"},
-		{"Host": "local.com", "Path" : "/8006", "Forward": "localhost:8006"},
-		{"Host": "local.com", "Path" : "/8007", "Forward": "localhost:8007"}
+A reverse proxy written in go that can front any number of microservices. It uses a rules file to map from requested host/path to microservice host/port/path.  Example rule file:
+
+```json
+	[
+	  {
+	    "host": "domain.com",
+	    "path": "/login",
+	    "forward": "localhost:9004",
+	    "secure": false
+	  },
+	  {
+	    "host": "domain.com",
+	    "path": "/ds/",
+	    "forward": "localhost:8081",
+	    "secure": true,
+	    "capabilities": {
+	        "GET": "read-ds",
+	        "POST": "write-ds",
+	        "PUT": "write-ds",
+	        "PATCH": "write-ds"
+	    }
+	  },
+	  {
+	    "host": "domain.com",
+	    "path": "/cachegroups/",
+	    "forward": "localhost:8082",
+	    "secure": true,
+	    "capabilities": {
+	        "GET": "read-cg",
+	        "POST": "write-cg",
+	        "PUT": "write-cg",
+	        "PATCH": "write-cg"
+	    }
+	  }
 	]
+```
 
+Note: Access "capabilities" are set in the rule file as a workaround, until TO DB tables are ready.
 
 No restart is needed to re-read the rule file and apply; within 60 seconds of a change in the file, it will pick up the new mappings.
 
-To run
-
-	go run webfront.go -rules=rules.json -https=:9000 -https_cert=server.pem -https_key=server.key 
-
-(or compile a binary, and run that)
-
-To get a token:
-
-	curl --insecure -Lkvs --header "Content-Type:application/json" -XPOST https://localhost:9000/login -d'{"username":"jvd", "password":"tootoo"}'
-   
-in my case that returned: 
-
-	{"Token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJQYXNzd29yZCI6InRvb3RvbyIsIlVzZXIiOiIiLCJleHAiOjE0NTg5NDg2MTl9.quCwZ5vghVBucxMxQ4fSfD84yw_yPEp9qLGGQNcHNUk"}``
-   
- Example:
-  
-	[jvd@laika webfront (master *=)]$ curl --insecure -Lkvs --header "Content-Type:application/json" -XPOST https://localhost:9000/login -d'{"username":"jvd", "password":"tootoo"}'
-	*   Trying ::1...
-	* Connected to localhost (::1) port 9000 (#0)
-	* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
-	* Server certificate: CU
-	> POST /login HTTP/1.1
-	> Host: localhost:9000
-	> User-Agent: curl/7.43.0
-	> Accept: */*
-	> Content-Type:application/json
-	> Content-Length: 39
-	>
-	* upload completely sent off: 39 out of 39 bytes
-	< HTTP/1.1 200 OK
-	< Content-Type: application/json
-	< Date: Thu, 24 Mar 2016 23:30:19 GMT
-	< Content-Length: 157
-	<
-	* Connection #0 to host localhost left intact
-	{"Token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJQYXNzd29yZCI6InRvb3RvbyIsIlVzZXIiOiIiLCJleHAiOjE0NTg5NDg2MTl9.quCwZ5vghVBucxMxQ4fSfD84yw_yPEp9qLGGQNcHNUk"}[jvd@laika webfront (master *=)]$
- 
- * To use a token: 
-
-	curl --insecure -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJQYXNzd29yZCI6InRvb3RvbyIsIlVzZXIiOiIiLCJleHAiOjE0NTg5NDg2MTl9.quCwZ5vghVBucxMxQ4fSfD84yw_yPEp9qLGGQNcHNUk' -Lkvs  https://localhost:9000/8003/r
+* To run:
+`go run webfront.go webfront.config my-secret`
+`secret` is used for jwt signing
 
-Example:
 
+* To login:
+`curl -X POST --insecure -Lkvs --header "Content-Type:application/json" https://localhost:9004/login -d'{"username":"foo", "password":"bar"}'`
    
-    [jvd@laika webfront (master *%=)]$ curl --insecure -H'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJQYXNzd29yZCI6InRvb3RvbyIsIlVzZXIiOiIiLCJleHAiOjE0NTg5NDg2MTl9.quCwZ5vghVBucxMxQ4fSfD84yw_yPEp9qLGGQNcHNUk' -Lkvs  https://localhost:9000/8003/r
-	*   Trying ::1...
-	* Connected to localhost (::1) port 9000 (#0)
-	* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
-	* Server certificate: CU
-	> GET /8003/r HTTP/1.1
-	> Host: localhost:9000
-	> User-Agent: curl/7.43.0
-	> Accept: */*
-	> Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJQYXNzd29yZCI6InRvb3RvbyIsIlVzZXIiOiIiLCJleHAiOjE0NTg5NDg2MTl9.quCwZ5vghVBucxMxQ4fSfD84yw_yPEp9qLGGQNcHNUk
-	>
-	< HTTP/1.1 200 OK
-	< Content-Length: 24
-	< Content-Type: text/plain; charset=utf-8
-	< Date: Thu, 24 Mar 2016 23:34:08 GMT
-	<
-	Hitting 8003 with /boo1
-	* Connection #0 to host localhost left intact
-	[jvd@laika webfront (master *%=)]$
+* To use a token:
+`curl --insecure -H'Authorization: Bearer <token>' -Lkvs  https://localhost:8080/ds/`
 
-	[jvd@laika webfront (master=)]$ curl --insecure -H'Authorization: Bearer FAKETOKEN' -Lkvs  https://localhost:9000/8003/r *   Trying ::1...
-	* Connected to localhost (::1) port 9000 (#0)
-	* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
-	* Server certificate: CU
-	> GET /8003/r HTTP/1.1
-	> Host: localhost:9000
-	> User-Agent: curl/7.43.0
-	> Accept: */*
-	> Authorization: Bearer FAKETOKEN
-	>
-	< HTTP/1.1 403 Forbidden
-	< Date: Thu, 24 Mar 2016 23:43:11 GMT
-	< Content-Length: 0
-	< Content-Type: text/plain; charset=utf-8
-	<
-	* Connection #0 to host localhost left intact
-	[jvd@laika webfront (master=)]$
-  
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/610f69c6/traffic_ops/experimental/webfront/rules.json
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/webfront/rules.json b/traffic_ops/experimental/webfront/rules.json
index fd6e792..46d9f28 100644
--- a/traffic_ops/experimental/webfront/rules.json
+++ b/traffic_ops/experimental/webfront/rules.json
@@ -1,32 +1,32 @@
 [
-  {
-    "host": "local.com",
-    "path": "/login",
-    "forward": "localhost:8080",
-    "secure": false
-  },
-  {
-    "host": "local.com",
-    "path": "/a",
-    "forward": "localhost:8081",
-    "secure": true,
-    "capabilities": {
-    	"GET": "read-a",
-    	"POST": "write-a",
-    	"PUT": "write-a",
-    	"PATCH": "write-a"
+    {
+        "host": "domain.com",
+        "path": "/login",
+        "forward": "localhost:9004",
+        "secure": false
+    },
+    {
+        "host": "domain.com",
+        "path": "/ds/",
+        "forward": "localhost:8081",
+        "secure": true,
+        "capabilities": {
+            "GET": "read-ds",
+            "POST": "write-ds",
+            "PUT": "write-ds",
+            "PATCH": "write-ds"
+        }
+    },
+    {
+        "host": "domain.com",
+        "path": "/cachegroups/",
+        "forward": "localhost:8082",
+        "secure": true,
+        "capabilities": {
+            "GET": "read-cg",
+            "POST": "write-cg",
+            "PUT": "write-cg",
+            "PATCH": "write-cg"
+        }
     }
-  },
-  {
-    "host": "local.com",
-    "path": "/b",
-    "forward": "localhost:8082",
-    "secure": true,
-    "capabilities": {
-    	"GET": "read-b",
-    	"POST": "write-b",
-    	"PUT": "write-b",
-    	"PATCH": "write-b"
-    }
-  }
 ]
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/610f69c6/traffic_ops/experimental/webfront/webfront.config
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/webfront/webfront.config b/traffic_ops/experimental/webfront/webfront.config
index f487dbd..b54f3df 100644
--- a/traffic_ops/experimental/webfront/webfront.config
+++ b/traffic_ops/experimental/webfront/webfront.config
@@ -1,5 +1,5 @@
 {
-	"httpsAddr": ":9000",
-	"ruleFile": "rules.json", 
-	"pollInterval": 60
-}
+	"rule-file": "rules.json",
+	"poll-interval": 60,
+	"listen-port": 8080
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/610f69c6/traffic_ops/experimental/webfront/webfront.go
----------------------------------------------------------------------
diff --git a/traffic_ops/experimental/webfront/webfront.go b/traffic_ops/experimental/webfront/webfront.go
index 76be08d..247ea24 100644
--- a/traffic_ops/experimental/webfront/webfront.go
+++ b/traffic_ops/experimental/webfront/webfront.go
@@ -13,14 +13,13 @@ import (
 	"net/http/httputil"
 	"os"
 	"path"
+	"strconv"
 	"strings"
 	"sync"
 	"time"
 )
 
-// TODO(amiry) - Handle token expiration
 // TODO(amiry) - Handle refresh tokens
-// TODO(amiry) - Where to keep the jwt secret? In the command line
 
 // Server implements an http.Handler that acts as a reverse proxy
 type Server struct {
@@ -47,20 +46,20 @@ type Claims struct {
 
 // Config holds the configuration of the server.
 type Config struct {
-	HTTPSAddr    string `json:"httpsAddr"`
-	RuleFile     string `json:"ruleFile"`
-	PollInterval int    `json:"pollInterval"`
+	RuleFile     string `json:"rule-file"`
+	PollInterval int    `json:"poll-interval"`
+	ListenPort   int    `json:"listen-port"`
 }
 
 var Logger *log.Logger
 
 func printUsage() {
 	exampleConfig := `{
-	"httpsAddr": ":9000",
-	"ruleFile": "rules.json",
-	"pollInterval": 60
+	"listen-port":   9000,
+	"rule-file":     "rules.json",
+	"poll-interval": 60
 }`
-	fmt.Println("Usage: " + path.Base(os.Args[0]) + " config-file")
+	fmt.Println("Usage: " + path.Base(os.Args[0]) + " config-file secret")
 	fmt.Println("")
 	fmt.Println("Example config-file:")
 	fmt.Println(exampleConfig)
@@ -68,7 +67,7 @@ func printUsage() {
 
 func main() {
 
-	if len(os.Args) < 2 {
+	if len(os.Args) < 3 {
 		printUsage()
 		return
 	}
@@ -80,6 +79,7 @@ func main() {
 		Logger.Println("Error opening config file:", err)
 		return
 	}
+
 	decoder := json.NewDecoder(file)
 	config := Config{}
 	err = decoder.Decode(&config)
@@ -87,7 +87,7 @@ func main() {
 		Logger.Println("Error reading config file:", err)
 		return
 	}
-	Logger.Println("Starting webfront...")
+
 	s, err := NewServer(config.RuleFile, time.Duration(config.PollInterval)*time.Second)
 	if err != nil {
 		Logger.Fatal(err)
@@ -102,7 +102,9 @@ func main() {
 	if _, err := os.Stat("server.key"); os.IsNotExist(err) {
 		Logger.Fatal("server.key file not found")
 	}
-	http.ListenAndServeTLS(config.HTTPSAddr, "server.pem", "server.key", s)
+
+	Logger.Printf("Starting webfront on port %d...", config.ListenPort)
+	Logger.Fatal(http.ListenAndServeTLS(":" + strconv.Itoa(int(config.ListenPort)), "server.pem", "server.key", s))
 }
 
 func validateToken(tokenString string) (*jwt.Token, error) {
@@ -112,7 +114,7 @@ func validateToken(tokenString string) (*jwt.Token, error) {
 		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
 			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
 		}
-		return []byte("CAmeRAFiveSevenNineNine"), nil
+		return []byte(os.Args[2]), nil
 	})
 	return token, err
 }
@@ -165,9 +167,8 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 			return
 		}
 
-		// Authorization: Check is the list of capabilities in the token's claims contains the reqired capability
-		// that is listed in the rule
-		Logger.Printf("Required capabilities %v", rule.Capabilities)
+		// Authorization: Check is the list of capabilities in the token's claims contains 
+		// the reqired capability that is listed in the rule
 		for _, c := range claims.Capabilities {
         	if c == rule.Capabilities[r.Method] {
 				isAuthorized = true
@@ -290,4 +291,4 @@ func makeHandler(r *Rule) http.Handler {
 		}
 	}
 	return nil
-}
+}
\ No newline at end of file