func validateTokenClaims(claims jwt.MapClaims, allowedRoles []string, userRequestTenantId string) error {
	if claims["authorities"] == nil {
		log.Error("Invalid token A")
		return errors.New(InvalidToken)
	}
	err := ValidateRole(claims, allowedRoles)
	if err != nil {
		return err
	}
	if claims["userId"] == nil {
		log.Error("Invalid token UI")
		return errors.New(InvalidToken)
	}
	if claims["user_name"] == nil {
		log.Error("Invalid token UN")
		return errors.New(InvalidToken)
	}
	err = claims.Valid()
	if err != nil {
		log.Error("token expired")
		return errors.New(InvalidToken)
	}
	if userRequestTenantId != "" {
		err = ValidateUserIdFromRequest(claims, userRequestTenantId)
		if err != nil {
			return err
		}
	}
	return nil
}
Validate token claims
package util
import (
	"crypto/tls"
	"crypto/x509"
	"errors"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/context"
	"github.com/dgrijalva/jwt-go"
	"github.com/go-playground/validator/v10"
	uuid "github.com/satori/go.uuid"
	log "github.com/sirupsen/logrus"
	"github.com/ulule/limiter/v3"
	"io/ioutil"
	"mecm-apprulemgr/models"
	"net/http"
	"os"
	"reflect"
	"regexp"
	"strconv"
	"strings"
)
var (
	jwtPublicKey = os.Getenv("JWT_PUBLIC_KEY")
)
const (
	MaxSize    int = 20
	MaxBackups int = 50
	MaxAge         = 30
	Post   = "POST"
	Get    = "GET"
	Put    = "PUT"
	Delete = "DELETE"
	Success = "SUCCESS"
	Failure = "FAILURE"
	DefaultRetryLimit    int = 30
	DefaultRetryInterval int = 2
	BadRequest          int = 400
	StatusUnauthorized  int = 401
	InternalServerError int = 500
	StatusForbidden     int = 403
	ClientIpaddressInvalid            = "client ip address is invalid"
	MarshalProgressModelError         = "failed to marshal progress model"
	MarshalAppRuleModelError          = "failed to marshal app rule model"
	UnMarshalAppRuleModelError        = "failed to unmarshal app rule model"
	UnknownRestMethod                 = "unknown rest method"
	FailedToWriteRes                  = "failed to write response into context"
	AppInstanceIdInvalid              = "app instance id is invalid"
	TenantIdInvalid                   = "tenant id is invalid"
	RequestBodyTooLarge               = "request body too large"
	IllegalTenantId            string = "illegal TenantId"
	Forbidden                  string = "forbidden"
	FailedToUnmarshal                 = "failed to unmarshal"
	AppRuleConfigSuccess = "app rule configured successfully"
	AppRuleConfigFailed  = "app rule configuration failed"
	AppRuleConfigTimeout = "app rule configuration timeout"
	AppInstanceId string = ":appInstanceId"
	TenantId      string = ":tenantId"
	MepAddress        = "MEP_SERVER_ADDR"
	MepPort           = "MEP_SERVER_PORT"
	DefaultMepAddress = "edgegallery"
	DefaultMepPort    = "80"
	HttpsUrl            string = "https://"
	AccessToken         string = "access_token"
	AuthorizationFailed string = "authorization failed"
	MecmTenantRole      string = "ROLE_MECM_TENANT"
	MecmAdminRole       string = "ROLE_MECM_ADMIN"
	MecmGuestRole       string = "ROLE_MECM_GUEST"
	InvalidToken        string = "invalid token"
	AppRuleConfigPath   string = "/tenants/:tenantId/app_instances/:appInstanceId/appd_configuration"
	AppRuleSyncPath     string = "/tenants/:tenantId/app_instances/appd_configuration"
	RequestBodyLength          = 4096
	NameRegex     = "^[\\d\\p{L}]*$|^[\\d\\p{L}][\\d\\p{L}_\\-]*[\\d\\p{L}]$"
)
var cipherSuiteMap = map[string]uint16{
	"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
	"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
}
type RateLimiter struct {
	GeneralLimiter *limiter.Limiter
}
func TLSConfig(crtName string) (*tls.Config, error) {
	certNameConfig := GetAppConfig(crtName)
	if len(certNameConfig) == 0 {
		log.Error(crtName + " configuration is not set")
		return nil, errors.New("cert name configuration is not set")
	}
	crt, err := ioutil.ReadFile(certNameConfig)
	if err != nil {
		log.Error("unable to read certificate")
		return nil, err
	}
	rootCAs := x509.NewCertPool()
	rootCAs.AppendCertsFromPEM(crt)
	sslCiphers := GetAppConfig("ssl_ciphers")
	if len(sslCiphers) == 0 {
		return nil, errors.New("TLS cipher configuration is not recommended or invalid")
	}
	cipherSuites := GetCipherSuites(sslCiphers)
	if cipherSuites == nil {
		return nil, errors.New("TLS cipher configuration is not recommended or invalid")
	}
	return &tls.Config{
		RootCAs:            rootCAs,
		MinVersion:         tls.VersionTLS12,
		CipherSuites:       cipherSuites,
		ServerName:         GetAppConfig("serverName"),
		InsecureSkipVerify: true,
	}, nil
}
func GetAppConfig(k string) string {
	return beego.AppConfig.String(k)
}
func GetCipherSuites(sslCiphers string) []uint16 {
	cipherSuiteArr := make([]uint16, 0, 5)
	cipherSuiteNameList := strings.Split(sslCiphers, ",")
	for _, cipherName := range cipherSuiteNameList {
		cipherName = strings.TrimSpace(cipherName)
		if len(cipherName) == 0 {
			continue
		}
		mapValue, ok := cipherSuiteMap[cipherName]
		if !ok {
			log.Error("not recommended cipher suite")
			return nil
		}
		cipherSuiteArr = append(cipherSuiteArr, mapValue)
	}
	if len(cipherSuiteArr) > 0 {
		return cipherSuiteArr
	}
	return nil
}
func ValidateIpv4Address(id string) error {
	if id == "" {
		return errors.New("require ip address")
	}
	validate := validator.New()
	return validate.Var(id, "required,ipv4")
}
func GetMepAddr() string {
	mepAddress := os.Getenv(MepAddress)
	if mepAddress == "" {
		mepAddress = DefaultMepAddress
	}
	return mepAddress
}
func GetMepPort() string {
	mepPort := os.Getenv(MepPort)
	if mepPort == "" {
		mepPort = DefaultMepPort
	}
	return mepPort
}
func GetRetryInterval() int {
	retryInterval := GetAppConfig("retryInterval")
	i, err := strconv.Atoi(retryInterval)
	if err != nil {
		i = DefaultRetryInterval
	}
	return i
}
func GetRetryLimit() int {
	retryLimit := GetAppConfig("retryLimit")
	i, err := strconv.Atoi(retryLimit)
	if err != nil {
		i = DefaultRetryLimit
	}
	return i
}
func DoRequest(req *http.Request) (*http.Response, error) {
	config, err := TLSConfig("SSL_ROOT_CERT")
	if err != nil {
		log.Error("unable to send request")
		return nil, err
	}
	tr := &http.Transport{
		TLSClientConfig: config,
	}
	client := &http.Client{Transport: tr}
	return client.Do(req)
}
func CreateAppdRuleUrl(appInstanceId string) string {
	url := HttpsUrl + GetMepAddr() + ":" + GetMepPort() + "/mepcfg/app_lcm/v1/applications/" +
		appInstanceId + "/appd_configuration"
	return url
}
func CreateTaskQueryUrl(taskId string) string {
	url := HttpsUrl + GetMepAddr() + ":" + GetMepPort() + "/mepcfg/app_lcm/v1/tasks/" +
		taskId + "/appd_configuration"
	return url
}
func ValidateAccessToken(accessToken string, allowedRoles []string, tenantId string) error {
	if accessToken == "" {
		return nil
	}
	claims := jwt.MapClaims{}
	token, err := jwt.ParseWithClaims(accessToken, claims, func(_ *jwt.Token) (interface{}, error) {
		return jwtPublicKey, nil
	})
	if token != nil && !token.Valid {
		err := validateTokenClaims(claims, allowedRoles, tenantId)
		if err != nil {
			return err
		}
	} else if er, ok := err.(*jwt.ValidationError); ok {
		if er.Errors&jwt.ValidationErrorMalformed != 0 {
			log.Error("Invalid token")
			return errors.New(InvalidToken)
		} else if er.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
			log.Error("token expired or inactive")
			return errors.New("token expired or inactive")
		} else {
			log.Error("Couldn't handle this token: ", err)
			return errors.New(err.Error())
		}
	} else {
		log.Error("Couldn't handle this token: ", err)
		return errors.New(err.Error())
	}
	log.Info("Token validated successfully")
	return nil
}