mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-28 21:25:55 +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)
|
oc.SendBadRequestError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Debugf("ID token from provider: %s", token.IDToken)
|
||||||
|
|
||||||
idToken, err := oidc.VerifyToken(ctx, token.IDToken)
|
idToken, err := oidc.VerifyToken(ctx, token.IDToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
oc.SendInternalServerError(err)
|
oc.SendInternalServerError(err)
|
||||||
@ -118,7 +120,6 @@ func (oc *OIDCController) Callback() {
|
|||||||
oc.SendInternalServerError(err)
|
oc.SendInternalServerError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debugf("Exchanged token string: %s", string(tokenBytes))
|
|
||||||
oc.SetSession(tokenKey, tokenBytes)
|
oc.SetSession(tokenKey, tokenBytes)
|
||||||
|
|
||||||
if u == nil {
|
if u == nil {
|
||||||
|
@ -115,6 +115,7 @@ func Init() {
|
|||||||
&configCtxModifier{},
|
&configCtxModifier{},
|
||||||
&secretReqCtxModifier{config.SecretStore},
|
&secretReqCtxModifier{config.SecretStore},
|
||||||
&oidcCliReqCtxModifier{},
|
&oidcCliReqCtxModifier{},
|
||||||
|
&idTokenReqCtxModifier{},
|
||||||
&authProxyReqCtxModifier{},
|
&authProxyReqCtxModifier{},
|
||||||
&robotAuthReqCtxModifier{},
|
&robotAuthReqCtxModifier{},
|
||||||
&basicAuthReqCtxModifier{},
|
&basicAuthReqCtxModifier{},
|
||||||
@ -260,6 +261,41 @@ func (oc *oidcCliReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
|
|||||||
return true
|
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{}
|
type authProxyReqCtxModifier struct{}
|
||||||
|
|
||||||
func (ap *authProxyReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
|
func (ap *authProxyReqCtxModifier) Modify(ctx *beegoctx.Context) bool {
|
||||||
|
@ -192,6 +192,31 @@ func TestOIDCCliReqCtxModifier(t *testing.T) {
|
|||||||
assert.Nil(t, err)
|
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) {
|
func TestRobotReqCtxModifier(t *testing.T) {
|
||||||
req, err := http.NewRequest(http.MethodGet,
|
req, err := http.NewRequest(http.MethodGet,
|
||||||
"http://127.0.0.1/api/projects/", nil)
|
"http://127.0.0.1/api/projects/", nil)
|
||||||
|
Loading…
Reference in New Issue
Block a user