diff --git a/pkg/auth/agent_local_authenticator.go b/pkg/auth/agent_local_authenticator.go index c7e8e823821..946771c6b01 100644 --- a/pkg/auth/agent_local_authenticator.go +++ b/pkg/auth/agent_local_authenticator.go @@ -10,7 +10,6 @@ import ( "github.com/go-openapi/runtime/security" "github.com/golang-jwt/jwt/v4" "github.com/openshift/assisted-service/internal/common" - "github.com/openshift/assisted-service/pkg/ocm" "github.com/pkg/errors" "github.com/sirupsen/logrus" ) @@ -80,7 +79,7 @@ func (a *AgentLocalAuthenticator) authenticateToken(token string) (interface{}, exp, found := claims["exp"].(float64) if !found { // exp claim is not found in the case of install workflow - return ocm.AdminPayload(), nil + return claims, nil } // in the case of addnodes workflow, check if the token is expired expTime := time.Unix(int64(exp), 0) @@ -89,7 +88,7 @@ func (a *AgentLocalAuthenticator) authenticateToken(token string) (interface{}, a.log.Error(err) return nil, common.NewInfraError(http.StatusUnauthorized, err) } - return ocm.AdminPayload(), nil + return claims, nil } func (a *AgentLocalAuthenticator) AuthAgentAuth(token string) (interface{}, error) { diff --git a/pkg/auth/agent_local_authz_handler.go b/pkg/auth/agent_local_authz_handler.go index 4a95d2b209e..a1b04bf47a4 100644 --- a/pkg/auth/agent_local_authz_handler.go +++ b/pkg/auth/agent_local_authz_handler.go @@ -5,11 +5,11 @@ import ( "errors" "fmt" "net/http" - "strings" "github.com/go-openapi/runtime/middleware" "github.com/golang-jwt/jwt/v4" "github.com/openshift/assisted-service/internal/common" + "github.com/openshift/assisted-service/restapi" "github.com/sirupsen/logrus" "gorm.io/gorm" ) @@ -58,49 +58,15 @@ func (a *AgentLocalAuthzHandler) authorizerMiddleware(request *http.Request) err } } -func JWTMiddleware(request *http.Request, authScheme string) (jwt.MapClaims, error) { - var authHeader string - switch authScheme { - // Agent authentication works with the "Authorization" header, but we explicitly set the "X-Secret-Key" header - // as it's the recommended header for assisted-installer-agent. The choice of header depends on the annotations - // in the swagger.yaml for the specific endpoint. - // For endpoints tagged with both agentAuth and userAuth, either "X-Secret-Key" or "Authorization" can be used. - // However, for ABI, we assume the three different user personas (agentAuth, userAuth, watcherAuth) have distinct roles. - // Therefore, we generate separate tokens for each persona and select the appropriate token based on the header. - // AuthAgentAuth could function with the "Authorization" header and the AuthUserAuth token if both agentAuth - // and userAuth are defined for the same endpoint. - case "agentAuth": - // AuthAgentAuth Applies when the "X-Secret-Key" header is set - // Refer assisted-installer-agent codebase - // used by agent service - authHeader = request.Header.Get("X-Secret-Key") - case "userAuth": - // AuthUserAuth Applies when the "Authorization" header is set - // used by ABI'S systemd services - authHeader = request.Header.Get("Authorization") - case "watcherAuth": - // AuthWatcherAuth Applies when the "Watcher-Authorization" header is set - // used by ABI's wait-for and monitor commands - authHeader = request.Header.Get("Watcher-Authorization") - default: - authHeader = "" - } - if authHeader == "" { - return nil, errors.New("missing authorization header") +func (a *AgentLocalAuthzHandler) agentInstallerAuthorizer(request *http.Request, authScheme string) error { + payload := request.Context().Value(restapi.AuthKey) + if payload == nil { + return common.NewApiError(http.StatusInternalServerError, fmt.Errorf("payload missing from authenticated context")) } - tokenString := strings.TrimPrefix(authHeader, "Bearer ") - - claims := jwt.MapClaims{} - _, _, err := new(jwt.Parser).ParseUnverified(tokenString, claims) - - return claims, err -} - -func (a *AgentLocalAuthzHandler) agentInstallerAuthorizer(request *http.Request, authScheme string) error { - claims, err := JWTMiddleware(request, authScheme) - if err != nil { - return common.NewApiError(http.StatusInternalServerError, fmt.Errorf("claims error: %s", err)) + claims, ok := payload.(jwt.MapClaims) + if !ok { + return common.NewApiError(http.StatusInternalServerError, fmt.Errorf("malformed claims payload")) } authClaim, ok := claims["auth_scheme"].(string) diff --git a/pkg/ocm/utils.go b/pkg/ocm/utils.go index e82312d6774..58ba7d49d55 100644 --- a/pkg/ocm/utils.go +++ b/pkg/ocm/utils.go @@ -48,7 +48,11 @@ func PayloadFromContext(ctx context.Context) *AuthPayload { // fallback to system-admin return AdminPayload() } - return payload.(*AuthPayload) + authPayload, ok := payload.(*AuthPayload) + if !ok { + return AdminPayload() + } + return authPayload } // UserNameFromContext returns username from the specified context