Auth: Use sessionStorage instead of cookie for automatic redirection (#92759)

* WIP: working as expected, has to be tested

* Rename query param, small changes

* Remove unused code

* Address feedback

* Cleanup

* Use the feature toggle to control the behaviour

* Use the toggle on the FE too

* Prevent the extra redirect/reload

 Co-authored-by: Josh Hunt <joshhunt@users.noreply.github.com>

* Return to login if user is not authenticated

* Add tracking issue

* Align BE redirect constructor to locationSvc
This commit is contained in:
Misi
2024-09-24 18:38:09 +02:00
committed by GitHub
co-authored by Josh Hunt
parent 18f8f38418
commit d411ce2664
15 changed files with 176 additions and 33 deletions
+37 -5
View File
@@ -44,14 +44,26 @@ func notAuthorized(c *contextmodel.ReqContext) {
return
}
writeRedirectCookie(c)
if !c.UseSessionStorageRedirect {
writeRedirectCookie(c)
}
if errors.Is(c.LookupTokenErr, authn.ErrTokenNeedsRotation) {
c.Redirect(setting.AppSubUrl + "/user/auth-tokens/rotate")
if !c.UseSessionStorageRedirect {
c.Redirect(setting.AppSubUrl + "/user/auth-tokens/rotate")
return
}
c.Redirect(setting.AppSubUrl + "/user/auth-tokens/rotate" + getRedirectToQueryParam(c))
return
}
c.Redirect(setting.AppSubUrl + "/login")
if !c.UseSessionStorageRedirect {
c.Redirect(setting.AppSubUrl + "/login")
return
}
c.Redirect(setting.AppSubUrl + "/login" + getRedirectToQueryParam(c))
}
func tokenRevoked(c *contextmodel.ReqContext, err *auth.TokenRevokedError) {
@@ -66,8 +78,13 @@ func tokenRevoked(c *contextmodel.ReqContext, err *auth.TokenRevokedError) {
return
}
writeRedirectCookie(c)
c.Redirect(setting.AppSubUrl + "/login")
if !c.UseSessionStorageRedirect {
writeRedirectCookie(c)
c.Redirect(setting.AppSubUrl + "/login")
return
}
c.Redirect(setting.AppSubUrl + "/login" + getRedirectToQueryParam(c))
}
func writeRedirectCookie(c *contextmodel.ReqContext) {
@@ -85,6 +102,21 @@ func writeRedirectCookie(c *contextmodel.ReqContext) {
cookies.WriteCookie(c.Resp, "redirect_to", url.QueryEscape(redirectTo), 0, nil)
}
func getRedirectToQueryParam(c *contextmodel.ReqContext) string {
redirectTo := c.Req.RequestURI
if setting.AppSubUrl != "" && strings.HasPrefix(redirectTo, setting.AppSubUrl) {
redirectTo = strings.TrimPrefix(redirectTo, setting.AppSubUrl)
}
if redirectTo == "/" {
return ""
}
// remove any forceLogin=true params
redirectTo = removeForceLoginParams(redirectTo)
return "?redirectTo=" + url.QueryEscape(redirectTo)
}
var forceLoginParamsRegexp = regexp.MustCompile(`&?forceLogin=true`)
func removeForceLoginParams(str string) string {
+1 -1
View File
@@ -33,7 +33,7 @@ func setupAuthMiddlewareTest(t *testing.T, identity *authn.Identity, authErr err
return contexthandler.ProvideService(setting.NewCfg(), tracing.InitializeTracerForTest(), &authntest.FakeService{
ExpectedErr: authErr,
ExpectedIdentity: identity,
})
}, featuremgmt.WithFeatures())
}
func TestAuth_Middleware(t *testing.T) {
+2 -1
View File
@@ -19,6 +19,7 @@ import (
"github.com/grafana/grafana/pkg/services/authn/authntest"
"github.com/grafana/grafana/pkg/services/contexthandler"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/navtree"
"github.com/grafana/grafana/pkg/services/user/usertest"
"github.com/grafana/grafana/pkg/setting"
@@ -290,5 +291,5 @@ func getContextHandler(t *testing.T, cfg *setting.Cfg, authnService authn.Servic
t.Helper()
tracer := tracing.InitializeTracerForTest()
return contexthandler.ProvideService(cfg, tracer, authnService)
return contexthandler.ProvideService(cfg, tracer, authnService, featuremgmt.WithFeatures())
}