-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add new go build tag no_openziti to reduce build size (#795)
* feat: Add new go build tag no_openziti to reduce build size closes #789 The usage of OpenZiti packages to support zero trust feature significantly increases the build size. For example, core-metadata increases from 14MB to 21MB, core-command increases from 9.8MB to 17MB, device-virtual increases from 18MB to 31MB, and app-service-configurable increases from 22Mb to 34MB. As many edge user scenarios require to deploy EdgeX services on resource-constrained devices without security, allowing that the services can be built without OpenZiti packages and ZeroTrust features can be helpful to user cases which don't need zero trust feature. This commit refactors the codes importing openziti packages with //go:build !no_openziti directive and creates para codes that don't use openziti packages with //go:build no_openziti directive, so users can simply build services by specifying no_openziti tag. Also remove vestigal zc variables and ZitiContext struct per discussion with https://github.com/dovholuknf in #659 (comment) Signed-off-by: Jude Hung <[email protected]> * feat: rename the zerotrust_no_ziti.go to no_ziti.go Signed-off-by: Jude Hung <[email protected]> --------- Signed-off-by: Jude Hung <[email protected]>
- Loading branch information
Showing
8 changed files
with
505 additions
and
240 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/******************************************************************************* | ||
* Copyright 2024 IOTech Ltd | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*******************************************************************************/ | ||
|
||
package handlers | ||
|
||
import ( | ||
"os" | ||
"strconv" | ||
|
||
"github.com/edgexfoundry/go-mod-core-contracts/v4/clients/logger" | ||
|
||
"github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/interfaces" | ||
"github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/secret" | ||
|
||
"github.com/labstack/echo/v4" | ||
) | ||
|
||
// NilAuthenticationHandlerFunc just invokes a nested handler | ||
func NilAuthenticationHandlerFunc() echo.MiddlewareFunc { | ||
return func(inner echo.HandlerFunc) echo.HandlerFunc { | ||
return func(c echo.Context) error { | ||
return inner(c) | ||
} | ||
} | ||
} | ||
|
||
// AutoConfigAuthenticationFunc auto-selects between a HandlerFunc | ||
// wrapper that does authentication and a HandlerFunc wrapper that does not. | ||
// By default, JWT validation is enabled in secure mode | ||
// (i.e. when using a real secrets provider instead of a no-op stub) | ||
// | ||
// Set EDGEX_DISABLE_JWT_VALIDATION to 1, t, T, TRUE, true, or True | ||
// to disable JWT validation. This might be wanted for an EdgeX | ||
// adopter that wanted to only validate JWT's at the proxy layer, | ||
// or as an escape hatch for a caller that cannot authenticate. | ||
func AutoConfigAuthenticationFunc(secretProvider interfaces.SecretProviderExt, lc logger.LoggingClient) echo.MiddlewareFunc { | ||
// Golang standard library treats an error as false | ||
disableJWTValidation, _ := strconv.ParseBool(os.Getenv("EDGEX_DISABLE_JWT_VALIDATION")) | ||
authenticationHook := NilAuthenticationHandlerFunc() | ||
if secret.IsSecurityEnabled() && !disableJWTValidation { | ||
authenticationHook = SecretStoreAuthenticationHandlerFunc(secretProvider, lc) | ||
} | ||
return authenticationHook | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
//go:build no_openziti | ||
|
||
/******************************************************************************* | ||
* Copyright 2024 IOTech Ltd | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*******************************************************************************/ | ||
|
||
package handlers | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"strings" | ||
|
||
"github.com/edgexfoundry/go-mod-core-contracts/v4/clients/logger" | ||
|
||
"github.com/edgexfoundry/go-mod-bootstrap/v4/bootstrap/interfaces" | ||
"github.com/labstack/echo/v4" | ||
) | ||
|
||
// SecretStoreAuthenticationHandlerFunc prefixes an existing HandlerFunc | ||
// with a OpenBao-based JWT authentication check. Usage: | ||
// | ||
// authenticationHook := handlers.NilAuthenticationHandlerFunc() | ||
// if secret.IsSecurityEnabled() { | ||
// lc := container.LoggingClientFrom(dic.Get) | ||
// secretProvider := container.SecretProviderFrom(dic.Get) | ||
// authenticationHook = handlers.SecretStoreAuthenticationHandlerFunc(secretProvider, lc) | ||
// } | ||
// For optionally-authenticated requests | ||
// r.HandleFunc("path", authenticationHook(handlerFunc)).Methods(http.MethodGet) | ||
// | ||
// For unauthenticated requests | ||
// r.HandleFunc("path", handlerFunc).Methods(http.MethodGet) | ||
// | ||
// For typical usage, it is preferred to use AutoConfigAuthenticationFunc which | ||
// will automatically select between a real and a fake JWT validation handler. | ||
func SecretStoreAuthenticationHandlerFunc(secretProvider interfaces.SecretProviderExt, lc logger.LoggingClient) echo.MiddlewareFunc { | ||
return func(inner echo.HandlerFunc) echo.HandlerFunc { | ||
return func(c echo.Context) error { | ||
r := c.Request() | ||
w := c.Response() | ||
authHeader := r.Header.Get("Authorization") | ||
lc.Debugf("Authorizing incoming call to '%s' via JWT (Authorization len=%d), %v", r.URL.Path, len(authHeader), secretProvider.IsZeroTrustEnabled()) | ||
|
||
if secretProvider.IsZeroTrustEnabled() { | ||
// this implementation will be pick up in the build when build tag no_openziti is specified, where | ||
// OpenZiti packages are not included and the Zero Trust feature is not available. | ||
lc.Info("zero trust was enabled, but service is built with no_openziti flag. falling back to token-based auth") | ||
} | ||
|
||
authParts := strings.Split(authHeader, " ") | ||
if len(authParts) >= 2 && strings.EqualFold(authParts[0], "Bearer") { | ||
token := authParts[1] | ||
validToken, err := secretProvider.IsJWTValid(token) | ||
if err != nil { | ||
lc.Errorf("Error checking JWT validity: %v", err) | ||
// set Response.Committed to true in order to rewrite the status code | ||
w.Committed = false | ||
return echo.NewHTTPError(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) | ||
} else if !validToken { | ||
lc.Warnf("Request to '%s' UNAUTHORIZED", r.URL.Path) | ||
// set Response.Committed to true in order to rewrite the status code | ||
w.Committed = false | ||
return echo.NewHTTPError(http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized)) | ||
} | ||
lc.Debugf("Request to '%s' authorized", r.URL.Path) | ||
return inner(c) | ||
} | ||
err := fmt.Errorf("unable to parse JWT for call to '%s'; unauthorized", r.URL.Path) | ||
lc.Errorf("%v", err) | ||
// set Response.Committed to true in order to rewrite the status code | ||
w.Committed = false | ||
return echo.NewHTTPError(http.StatusUnauthorized, http.StatusText(http.StatusUnauthorized)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.