mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-25 03:35:21 +01:00
Add filter to handle request with ID token (#7759)
This commit allows request with a valid ID token to access the API. Signed-off-by: Daniel Jiang <jiangd@vmware.com>
This commit is contained in:
parent
439b44c61f
commit
d81afe274c
@ -91,6 +91,8 @@ func (oc *OIDCController) Callback() {
|
||||
oc.SendBadRequestError(err)
|
||||
return
|
||||
}
|
||||
log.Debugf("ID token from provider: %s", token.IDToken)
|
||||
|
||||
idToken, err := oidc.VerifyToken(ctx, token.IDToken)
|
||||
if err != nil {
|
||||
oc.SendInternalServerError(err)
|
||||
@ -118,7 +120,6 @@ func (oc *OIDCController) Callback() {
|
||||
oc.SendInternalServerError(err)
|
||||
return
|
||||
}
|
||||
log.Debugf("Exchanged token string: %s", string(tokenBytes))
|
||||
oc.SetSession(tokenKey, tokenBytes)
|
||||
|
||||
if u == nil {
|
||||
|
@ -115,6 +115,7 @@ func Init() {
|
||||
&configCtxModifier{},
|
||||
&secretReqCtxModifier{config.SecretStore},
|
||||
&oidcCliReqCtxModifier{},
|
||||
&idTokenReqCtxModifier{},
|
||||
&authProxyReqCtxModifier{},
|
||||
&robotAuthReqCtxModifier{},
|
||||
&basicAuthReqCtxModifier{},
|
||||
@ -260,6 +261,41 @@ func (oc *oidcCliReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type idTokenReqCtxModifier struct{}
|
||||
|
||||
func (it *idTokenReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
|
||||
req := ctx.Request
|
||||
if req.Context().Value(AuthModeKey).(string) != common.OIDCAuth {
|
||||
return false
|
||||
}
|
||||
if !strings.HasPrefix(ctx.Request.URL.Path, "/api") {
|
||||
return false
|
||||
}
|
||||
h := req.Header.Get("Authorization")
|
||||
token := strings.Split(h, "Bearer")
|
||||
if len(token) < 2 {
|
||||
return false
|
||||
}
|
||||
claims, err := oidc.VerifyToken(req.Context(), strings.TrimSpace(token[1]))
|
||||
if err != nil {
|
||||
log.Warningf("Failed to verify token, error: %v", err)
|
||||
return false
|
||||
}
|
||||
u, err := dao.GetUserBySubIss(claims.Subject, claims.Issuer)
|
||||
if err != nil {
|
||||
log.Warningf("Failed to get user based on token claims, error: %v", err)
|
||||
return false
|
||||
}
|
||||
if u == nil {
|
||||
log.Warning("User matches token's claims is not onboarded.")
|
||||
return false
|
||||
}
|
||||
pm := config.GlobalProjectMgr
|
||||
sc := local.NewSecurityContext(u, pm)
|
||||
setSecurCtxAndPM(ctx.Request, sc, pm)
|
||||
return true
|
||||
}
|
||||
|
||||
type authProxyReqCtxModifier struct{}
|
||||
|
||||
func (ap *authProxyReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
|
||||
|
@ -192,6 +192,31 @@ func TestOIDCCliReqCtxModifier(t *testing.T) {
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestIdTokenReqCtxModifier(t *testing.T) {
|
||||
bc := context.Background()
|
||||
it := &idTokenReqCtxModifier{}
|
||||
r1, err := http.NewRequest(http.MethodGet,
|
||||
"http://127.0.0.1/chartrepo/", nil)
|
||||
require.Nil(t, err)
|
||||
req1 := r1.WithContext(context.WithValue(bc, AuthModeKey, common.DBAuth))
|
||||
ctx1, err := newContext(req1)
|
||||
require.Nil(t, err)
|
||||
assert.False(t, it.Modify(ctx1))
|
||||
|
||||
req2 := r1.WithContext(context.WithValue(bc, AuthModeKey, common.OIDCAuth))
|
||||
ctx2, err := newContext(req2)
|
||||
require.Nil(t, err)
|
||||
assert.False(t, it.Modify(ctx2))
|
||||
|
||||
r2, err := http.NewRequest(http.MethodGet,
|
||||
"http://127.0.0.1/api/projects/", nil)
|
||||
require.Nil(t, err)
|
||||
req3 := r2.WithContext(context.WithValue(bc, AuthModeKey, common.OIDCAuth))
|
||||
ctx3, err := newContext(req3)
|
||||
require.Nil(t, err)
|
||||
assert.False(t, it.Modify(ctx3))
|
||||
}
|
||||
|
||||
func TestRobotReqCtxModifier(t *testing.T) {
|
||||
req, err := http.NewRequest(http.MethodGet,
|
||||
"http://127.0.0.1/api/projects/", nil)
|
||||
|
Loading…
Reference in New Issue
Block a user