mirror of https://github.com/grafana/grafana
Auth: Support for user authentication via reverse proxy header (like X-Authenticated-User, or X-WEBAUTH-USER), Closes #1921
parent
ba883d25fe
commit
be589d81c7
@ -0,0 +1,67 @@ |
||||
package middleware |
||||
|
||||
import ( |
||||
"github.com/grafana/grafana/pkg/bus" |
||||
m "github.com/grafana/grafana/pkg/models" |
||||
"github.com/grafana/grafana/pkg/setting" |
||||
) |
||||
|
||||
func initContextWithAuthProxy(ctx *Context) bool { |
||||
if !setting.AuthProxyEnabled { |
||||
return false |
||||
} |
||||
|
||||
proxyHeaderValue := ctx.Req.Header.Get(setting.AuthProxyHeaderName) |
||||
if len(proxyHeaderValue) <= 0 { |
||||
return false |
||||
} |
||||
|
||||
query := getSignedInUserQueryForProxyAuth(proxyHeaderValue) |
||||
if err := bus.Dispatch(query); err != nil { |
||||
if err != m.ErrUserNotFound { |
||||
ctx.Handle(500, "Failed find user specifed in auth proxy header", err) |
||||
return true |
||||
} |
||||
|
||||
if setting.AuthProxyAutoSignUp { |
||||
cmd := getCreateUserCommandForProxyAuth(proxyHeaderValue) |
||||
if err := bus.Dispatch(cmd); err != nil { |
||||
ctx.Handle(500, "Failed to create user specified in auth proxy header", err) |
||||
return true |
||||
} |
||||
query = &m.GetSignedInUserQuery{UserId: cmd.Result.Id} |
||||
if err := bus.Dispatch(query); err != nil { |
||||
ctx.Handle(500, "Failed find user after creation", err) |
||||
return true |
||||
} |
||||
} |
||||
} |
||||
|
||||
ctx.SignedInUser = query.Result |
||||
ctx.IsSignedIn = true |
||||
return true |
||||
} |
||||
|
||||
func getSignedInUserQueryForProxyAuth(headerVal string) *m.GetSignedInUserQuery { |
||||
query := m.GetSignedInUserQuery{} |
||||
if setting.AuthProxyHeaderProperty == "username" { |
||||
query.Login = headerVal |
||||
} else if setting.AuthProxyHeaderProperty == "email" { |
||||
query.Email = headerVal |
||||
} else { |
||||
panic("Auth proxy header property invalid") |
||||
} |
||||
return &query |
||||
} |
||||
|
||||
func getCreateUserCommandForProxyAuth(headerVal string) *m.CreateUserCommand { |
||||
cmd := m.CreateUserCommand{} |
||||
if setting.AuthProxyHeaderProperty == "username" { |
||||
cmd.Login = headerVal |
||||
} else if setting.AuthProxyHeaderProperty == "email" { |
||||
cmd.Email = headerVal |
||||
} else { |
||||
panic("Auth proxy header property invalid") |
||||
} |
||||
return &cmd |
||||
} |
||||
@ -0,0 +1,35 @@ |
||||
package middleware |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
. "github.com/smartystreets/goconvey/convey" |
||||
) |
||||
|
||||
func TestMiddlewareAuth(t *testing.T) { |
||||
|
||||
Convey("Given the grafana middleware", t, func() { |
||||
reqSignIn := Auth(&AuthOptions{ReqSignedIn: true}) |
||||
|
||||
middlewareScenario("ReqSignIn true and unauthenticated request", func(sc *scenarioContext) { |
||||
sc.m.Get("/secure", reqSignIn, sc.defaultHandler) |
||||
|
||||
sc.fakeReq("GET", "/secure").exec() |
||||
|
||||
Convey("Should redirect to login", func() { |
||||
So(sc.resp.Code, ShouldEqual, 302) |
||||
}) |
||||
}) |
||||
|
||||
middlewareScenario("ReqSignIn true and unauthenticated API request", func(sc *scenarioContext) { |
||||
sc.m.Get("/api/secure", reqSignIn, sc.defaultHandler) |
||||
|
||||
sc.fakeReq("GET", "/api/secure").exec() |
||||
|
||||
Convey("Should return 401", func() { |
||||
So(sc.resp.Code, ShouldEqual, 401) |
||||
}) |
||||
}) |
||||
|
||||
}) |
||||
} |
||||
Loading…
Reference in new issue