You've already forked oauth2-proxy
mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2025-06-15 00:15:00 +02:00
Support nonce checks in OIDC Provider (#967)
* Set and verify a nonce with OIDC * Create a CSRF object to manage nonces & cookies * Add missing generic cookie unit tests * Add config flag to control OIDC SkipNonce * Send hashed nonces in authentication requests * Encrypt the CSRF cookie * Add clarity to naming & add more helper methods * Make CSRF an interface and keep underlying nonces private * Add ReverseProxy scope to cookie tests * Align to new 1.16 SameSite cookie default * Perform SecretBytes conversion on CSRF cookie crypto * Make state encoding signatures consistent * Mock time in CSRF struct via Clock * Improve InsecureSkipNonce docstring
This commit is contained in:
@ -22,6 +22,7 @@ import (
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/cookies"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger"
|
||||
sessionscookie "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/sessions/cookie"
|
||||
"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/upstream"
|
||||
@ -698,23 +699,42 @@ func (patTest *PassAccessTokenTest) Close() {
|
||||
patTest.providerServer.Close()
|
||||
}
|
||||
|
||||
func (patTest *PassAccessTokenTest) getCallbackEndpoint() (httpCode int,
|
||||
cookie string) {
|
||||
func (patTest *PassAccessTokenTest) getCallbackEndpoint() (httpCode int, cookie string) {
|
||||
rw := httptest.NewRecorder()
|
||||
req, err := http.NewRequest("GET", "/oauth2/callback?code=callback_code&state=nonce:",
|
||||
strings.NewReader(""))
|
||||
|
||||
csrf, err := cookies.NewCSRF(patTest.proxy.CookieOptions)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(
|
||||
http.MethodGet,
|
||||
fmt.Sprintf(
|
||||
"/oauth2/callback?code=callback_code&state=%s",
|
||||
encodeState(csrf.HashOAuthState(), "%2F"),
|
||||
),
|
||||
strings.NewReader(""),
|
||||
)
|
||||
if err != nil {
|
||||
return 0, ""
|
||||
}
|
||||
req.AddCookie(patTest.proxy.MakeCSRFCookie(req, "nonce", time.Hour, time.Now()))
|
||||
|
||||
// rw is a dummy here, we just want the csrfCookie to add to our req
|
||||
csrfCookie, err := csrf.SetCookie(httptest.NewRecorder(), req)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
req.AddCookie(csrfCookie)
|
||||
|
||||
patTest.proxy.ServeHTTP(rw, req)
|
||||
|
||||
return rw.Code, rw.Header().Values("Set-Cookie")[1]
|
||||
}
|
||||
|
||||
// getEndpointWithCookie makes a requests againt the oauthproxy with passed requestPath
|
||||
// and cookie and returns body and status code.
|
||||
func (patTest *PassAccessTokenTest) getEndpointWithCookie(cookie string, endpoint string) (httpCode int, accessToken string) {
|
||||
cookieName := patTest.opts.Cookie.Name
|
||||
cookieName := patTest.proxy.CookieOptions.Name
|
||||
var value string
|
||||
keyPrefix := cookieName + "="
|
||||
|
||||
@ -983,6 +1003,9 @@ func NewProcessCookieTest(opts ProcessCookieTestOpts, modifiers ...OptionsModifi
|
||||
}
|
||||
pcTest.proxy.provider.(*TestProvider).SetAllowedGroups(pcTest.opts.Providers[0].AllowedGroups)
|
||||
|
||||
// Now, zero-out proxy.CookieRefresh for the cases that don't involve
|
||||
// access_token validation.
|
||||
pcTest.proxy.CookieOptions.Refresh = time.Duration(0)
|
||||
pcTest.rw = httptest.NewRecorder()
|
||||
pcTest.req, _ = http.NewRequest("GET", "/", strings.NewReader(""))
|
||||
pcTest.validateUser = true
|
||||
@ -1104,6 +1127,7 @@ func TestProcessCookieFailIfRefreshSetAndCookieExpired(t *testing.T) {
|
||||
err = pcTest.SaveSession(startSession)
|
||||
assert.NoError(t, err)
|
||||
|
||||
pcTest.proxy.CookieOptions.Refresh = time.Hour
|
||||
session, err := pcTest.LoadCookiedSession()
|
||||
assert.NotEqual(t, nil, err)
|
||||
if session != nil {
|
||||
@ -1999,7 +2023,7 @@ func TestClearSplitCookie(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
p := OAuthProxy{sessionStore: store}
|
||||
p := OAuthProxy{CookieOptions: &opts.Cookie, sessionStore: store}
|
||||
var rw = httptest.NewRecorder()
|
||||
req := httptest.NewRequest("get", "/", nil)
|
||||
|
||||
@ -2032,7 +2056,7 @@ func TestClearSingleCookie(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
p := OAuthProxy{sessionStore: store}
|
||||
p := OAuthProxy{CookieOptions: &opts.Cookie, sessionStore: store}
|
||||
var rw = httptest.NewRecorder()
|
||||
req := httptest.NewRequest("get", "/", nil)
|
||||
|
||||
|
Reference in New Issue
Block a user