Add basic auth to dashboard

This commit is contained in:
Eric Larssen 2016-08-13 09:32:11 -05:00 committed by Damon Zhao
parent b403e4142b
commit 4dadaac905
5 changed files with 86 additions and 23 deletions

View File

@ -149,9 +149,12 @@ Configure a port for dashboard to enable this feature:
```ini ```ini
[common] [common]
dashboard_port = 7500 dashboard_port = 7500
# dashboard's username and password are both optionalif not set, default is admin.
dashboard_username = abc
dashboard_password = abc
``` ```
Then visit `http://[server_addr]:7500` to see dashboard. Then visit `http://[server_addr]:7500` to see dashboard, default username and password are both `admin`.
![dashboard](/doc/pic/dashboard.png) ![dashboard](/doc/pic/dashboard.png)

View File

@ -146,9 +146,12 @@ frp 目前正在前期开发阶段master 分支用于发布稳定版本dev
```ini ```ini
[common] [common]
dashboard_port = 7500 dashboard_port = 7500
# dashboard 用户名密码可选,默认都为 admin
dashboard_username = abc
dashboard_password = abc
``` ```
打开浏览器通过 `http://[server_addr]:7500` 访问 dashboard 界面。 打开浏览器通过 `http://[server_addr]:7500` 访问 dashboard 界面,用户名密码默认为 `admin`
![dashboard](/doc/pic/dashboard.png) ![dashboard](/doc/pic/dashboard.png)

View File

@ -9,6 +9,9 @@ vhost_http_port = 80
vhost_https_port = 443 vhost_https_port = 443
# if you want to configure or reload frps by dashboard, dashboard_port must be set # if you want to configure or reload frps by dashboard, dashboard_port must be set
dashboard_port = 7500 dashboard_port = 7500
# dashboard username and password for basic protect, if not set, both default value is admin
dashboard_username = abc
dashboard_password = abc
# dashboard assets directory(only for debug mode) # dashboard assets directory(only for debug mode)
# assets_dir = ./static # assets_dir = ./static
# console or real logFile path like ./frps.log # console or real logFile path like ./frps.log

View File

@ -36,6 +36,8 @@ var (
VhostHttpPort int64 = 0 // if VhostHttpPort equals 0, don't listen a public port for http protocol VhostHttpPort int64 = 0 // if VhostHttpPort equals 0, don't listen a public port for http protocol
VhostHttpsPort int64 = 0 // if VhostHttpsPort equals 0, don't listen a public port for https protocol VhostHttpsPort int64 = 0 // if VhostHttpsPort equals 0, don't listen a public port for https protocol
DashboardPort int64 = 0 // if DashboardPort equals 0, dashboard is not available DashboardPort int64 = 0 // if DashboardPort equals 0, dashboard is not available
DashboardUsername string = "admin"
DashboardPassword string = "admin"
AssetsDir string = "" AssetsDir string = ""
LogFile string = "console" LogFile string = "console"
LogWay string = "console" // console or file LogWay string = "console" // console or file
@ -119,6 +121,16 @@ func loadCommonConf(confFile string) error {
DashboardPort = 0 DashboardPort = 0
} }
tmpStr, ok = conf.Get("common", "dashboard_username")
if ok {
DashboardUsername = tmpStr
}
tmpStr, ok = conf.Get("common", "dashboard_password")
if ok {
DashboardPassword = tmpStr
}
tmpStr, ok = conf.Get("common", "assets_dir") tmpStr, ok = conf.Get("common", "assets_dir")
if ok { if ok {
AssetsDir = tmpStr AssetsDir = tmpStr

View File

@ -15,9 +15,11 @@
package server package server
import ( import (
"encoding/base64"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
"strings"
"time" "time"
"github.com/fatedier/frp/src/assets" "github.com/fatedier/frp/src/assets"
@ -38,7 +40,7 @@ func RunDashboardServer(addr string, port int64) (err error) {
// view, see dashboard_view.go // view, see dashboard_view.go
mux.Handle("/favicon.ico", http.FileServer(assets.FileSystem)) mux.Handle("/favicon.ico", http.FileServer(assets.FileSystem))
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(assets.FileSystem))) mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(assets.FileSystem)))
mux.HandleFunc("/", viewDashboard) mux.HandleFunc("/", use(viewDashboard, basicAuth))
address := fmt.Sprintf("%s:%d", addr, port) address := fmt.Sprintf("%s:%d", addr, port)
server := &http.Server{ server := &http.Server{
@ -58,3 +60,43 @@ func RunDashboardServer(addr string, port int64) (err error) {
go server.Serve(ln) go server.Serve(ln)
return return
} }
func use(h http.HandlerFunc, middleware ...func(http.HandlerFunc) http.HandlerFunc) http.HandlerFunc {
for _, m := range middleware {
h = m(h)
}
return h
}
func basicAuth(h http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
s := strings.SplitN(r.Header.Get("Authorization"), " ", 2)
if len(s) != 2 {
http.Error(w, "Not authorized", 401)
return
}
b, err := base64.StdEncoding.DecodeString(s[1])
if err != nil {
http.Error(w, err.Error(), 401)
return
}
pair := strings.SplitN(string(b), ":", 2)
if len(pair) != 2 {
http.Error(w, "Not authorized", 401)
return
}
if pair[0] != DashboardUsername || pair[1] != DashboardPassword {
http.Error(w, "Not authorized", 401)
return
}
h.ServeHTTP(w, r)
}
}