mirror of
https://github.com/oauth2-proxy/oauth2-proxy.git
synced 2024-11-28 09:08:44 +02:00
Authorize in Redeem callback flow
This commit is contained in:
parent
1b3b00443a
commit
f21b3b8b20
@ -7,7 +7,7 @@
|
|||||||
- [#905](https://github.com/oauth2-proxy/oauth2-proxy/pull/905) Existing sessions from v6.0.0 or earlier are no longer valid. They will trigger a reauthentication.
|
- [#905](https://github.com/oauth2-proxy/oauth2-proxy/pull/905) Existing sessions from v6.0.0 or earlier are no longer valid. They will trigger a reauthentication.
|
||||||
- [#826](https://github.com/oauth2-proxy/oauth2-proxy/pull/826) `skip-auth-strip-headers` now applies to all requests, not just those where authentication would be skipped.
|
- [#826](https://github.com/oauth2-proxy/oauth2-proxy/pull/826) `skip-auth-strip-headers` now applies to all requests, not just those where authentication would be skipped.
|
||||||
- [#797](https://github.com/oauth2-proxy/oauth2-proxy/pull/797) The behavior of the Google provider Groups restriction changes with this
|
- [#797](https://github.com/oauth2-proxy/oauth2-proxy/pull/797) The behavior of the Google provider Groups restriction changes with this
|
||||||
- Either `--google-group` or the new `--allowed-group` will work for Google now (`--google-group` will be used it both are set)
|
- Either `--google-group` or the new `--allowed-group` will work for Google now (`--google-group` will be used if both are set)
|
||||||
- Group membership lists will be passed to the backend with the `X-Forwarded-Groups` header
|
- Group membership lists will be passed to the backend with the `X-Forwarded-Groups` header
|
||||||
- If you change the list of allowed groups, existing sessions that now don't have a valid group will be logged out immediately.
|
- If you change the list of allowed groups, existing sessions that now don't have a valid group will be logged out immediately.
|
||||||
- Previously, group membership was only checked on session creation and refresh.
|
- Previously, group membership was only checked on session creation and refresh.
|
||||||
|
@ -907,11 +907,15 @@ func (p *OAuthProxy) OAuthCallback(rw http.ResponseWriter, req *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set cookie, or deny
|
// set cookie, or deny
|
||||||
if p.Validator(session.Email) {
|
authorized, err := p.provider.Authorize(req.Context(), session)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Error with authorization: %v", err)
|
||||||
|
}
|
||||||
|
if p.Validator(session.Email) && authorized {
|
||||||
logger.PrintAuthf(session.Email, req, logger.AuthSuccess, "Authenticated via OAuth2: %s", session)
|
logger.PrintAuthf(session.Email, req, logger.AuthSuccess, "Authenticated via OAuth2: %s", session)
|
||||||
err := p.SaveSession(rw, req, session)
|
err := p.SaveSession(rw, req, session)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Printf("Error saving session state for %s: %v", remoteAddr, err)
|
logger.Errorf("Error saving session state for %s: %v", remoteAddr, err)
|
||||||
p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
|
p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -28,13 +28,13 @@ type GoogleProvider struct {
|
|||||||
|
|
||||||
RedeemRefreshURL *url.URL
|
RedeemRefreshURL *url.URL
|
||||||
|
|
||||||
// GroupValidator is a function that determines if the user in the passed
|
// groupValidator is a function that determines if the user in the passed
|
||||||
// session is a member of any of the configured Google groups.
|
// session is a member of any of the configured Google groups.
|
||||||
//
|
//
|
||||||
// This hits the Google API for each group, so it is called on Redeem &
|
// This hits the Google API for each group, so it is called on Redeem &
|
||||||
// Refresh. `Authorize` uses the results of this saved in `session.Groups`
|
// Refresh. `Authorize` uses the results of this saved in `session.Groups`
|
||||||
// Since it is called on every request.
|
// Since it is called on every request.
|
||||||
GroupValidator func(*sessions.SessionState) bool
|
groupValidator func(*sessions.SessionState) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Provider = (*GoogleProvider)(nil)
|
var _ Provider = (*GoogleProvider)(nil)
|
||||||
@ -90,9 +90,9 @@ func NewGoogleProvider(p *ProviderData) *GoogleProvider {
|
|||||||
})
|
})
|
||||||
return &GoogleProvider{
|
return &GoogleProvider{
|
||||||
ProviderData: p,
|
ProviderData: p,
|
||||||
// Set a default GroupValidator to just always return valid (true), it will
|
// Set a default groupValidator to just always return valid (true), it will
|
||||||
// be overwritten if we configured a Google group restriction.
|
// be overwritten if we configured a Google group restriction.
|
||||||
GroupValidator: func(*sessions.SessionState) bool {
|
groupValidator: func(*sessions.SessionState) bool {
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -165,7 +165,8 @@ func (p *GoogleProvider) Redeem(ctx context.Context, redirectURL, code string) (
|
|||||||
|
|
||||||
created := time.Now()
|
created := time.Now()
|
||||||
expires := time.Now().Add(time.Duration(jsonResponse.ExpiresIn) * time.Second).Truncate(time.Second)
|
expires := time.Now().Add(time.Duration(jsonResponse.ExpiresIn) * time.Second).Truncate(time.Second)
|
||||||
s := &sessions.SessionState{
|
|
||||||
|
return &sessions.SessionState{
|
||||||
AccessToken: jsonResponse.AccessToken,
|
AccessToken: jsonResponse.AccessToken,
|
||||||
IDToken: jsonResponse.IDToken,
|
IDToken: jsonResponse.IDToken,
|
||||||
CreatedAt: &created,
|
CreatedAt: &created,
|
||||||
@ -173,19 +174,26 @@ func (p *GoogleProvider) Redeem(ctx context.Context, redirectURL, code string) (
|
|||||||
RefreshToken: jsonResponse.RefreshToken,
|
RefreshToken: jsonResponse.RefreshToken,
|
||||||
Email: c.Email,
|
Email: c.Email,
|
||||||
User: c.Subject,
|
User: c.Subject,
|
||||||
}
|
}, nil
|
||||||
p.GroupValidator(s)
|
}
|
||||||
|
|
||||||
return s, nil
|
// EnrichSessionState checks the listed Google Groups configured and adds any
|
||||||
|
// that the user is a member of to session.Groups.
|
||||||
|
func (p *GoogleProvider) EnrichSessionState(ctx context.Context, s *sessions.SessionState) error {
|
||||||
|
p.groupValidator(s)
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetGroupRestriction configures the GoogleProvider to restrict access to the
|
// SetGroupRestriction configures the GoogleProvider to restrict access to the
|
||||||
// specified group(s). AdminEmail has to be an administrative email on the domain that is
|
// specified group(s). AdminEmail has to be an administrative email on the domain that is
|
||||||
// checked. CredentialsFile is the path to a json file containing a Google service
|
// checked. CredentialsFile is the path to a json file containing a Google service
|
||||||
// account credentials.
|
// account credentials.
|
||||||
|
//
|
||||||
|
// TODO (@NickMeves) - Unit Test this OR refactor away from groupValidator func
|
||||||
func (p *GoogleProvider) SetGroupRestriction(groups []string, adminEmail string, credentialsReader io.Reader) {
|
func (p *GoogleProvider) SetGroupRestriction(groups []string, adminEmail string, credentialsReader io.Reader) {
|
||||||
adminService := getAdminService(adminEmail, credentialsReader)
|
adminService := getAdminService(adminEmail, credentialsReader)
|
||||||
p.GroupValidator = func(s *sessions.SessionState) bool {
|
p.groupValidator = func(s *sessions.SessionState) bool {
|
||||||
// Reset our saved Groups in case membership changed
|
// Reset our saved Groups in case membership changed
|
||||||
// This is used by `Authorize` on every request
|
// This is used by `Authorize` on every request
|
||||||
s.Groups = make([]string, 0, len(groups))
|
s.Groups = make([]string, 0, len(groups))
|
||||||
@ -266,7 +274,7 @@ func (p *GoogleProvider) RefreshSessionIfNeeded(ctx context.Context, s *sessions
|
|||||||
}
|
}
|
||||||
|
|
||||||
// re-check that the user is in the proper google group(s)
|
// re-check that the user is in the proper google group(s)
|
||||||
if !p.GroupValidator(s) {
|
if !p.groupValidator(s) {
|
||||||
return false, fmt.Errorf("%s is no longer in the group(s)", s.Email)
|
return false, fmt.Errorf("%s is no longer in the group(s)", s.Email)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ func TestGoogleProviderGroupValidator(t *testing.T) {
|
|||||||
validatorFunc func(*sessions.SessionState) bool
|
validatorFunc func(*sessions.SessionState) bool
|
||||||
expectedAuthZ bool
|
expectedAuthZ bool
|
||||||
}{
|
}{
|
||||||
"Email is authorized with GroupValidator": {
|
"Email is authorized with groupValidator": {
|
||||||
session: &sessions.SessionState{
|
session: &sessions.SessionState{
|
||||||
Email: sessionEmail,
|
Email: sessionEmail,
|
||||||
},
|
},
|
||||||
@ -127,7 +127,7 @@ func TestGoogleProviderGroupValidator(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expectedAuthZ: true,
|
expectedAuthZ: true,
|
||||||
},
|
},
|
||||||
"Email is denied with GroupValidator": {
|
"Email is denied with groupValidator": {
|
||||||
session: &sessions.SessionState{
|
session: &sessions.SessionState{
|
||||||
Email: sessionEmail,
|
Email: sessionEmail,
|
||||||
},
|
},
|
||||||
@ -149,9 +149,9 @@ func TestGoogleProviderGroupValidator(t *testing.T) {
|
|||||||
g := NewWithT(t)
|
g := NewWithT(t)
|
||||||
p := newGoogleProvider()
|
p := newGoogleProvider()
|
||||||
if tc.validatorFunc != nil {
|
if tc.validatorFunc != nil {
|
||||||
p.GroupValidator = tc.validatorFunc
|
p.groupValidator = tc.validatorFunc
|
||||||
}
|
}
|
||||||
g.Expect(p.GroupValidator(tc.session)).To(Equal(tc.expectedAuthZ))
|
g.Expect(p.groupValidator(tc.session)).To(Equal(tc.expectedAuthZ))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user