Пример #1
2
// NewToken creates new JWT token for the gien username. It embedds the given
// public key as kontrolKey and signs the token with the private one.
func NewToken(username, private, public string) *jwt.Token {
	tknID := uuid.NewV4()

	hostname, err := os.Hostname()
	if err != nil {
		panic(err)
	}

	if username == "" {
		username = "******"
	}

	if testuser := os.Getenv("TESTKEY_USERNAME"); testuser != "" {
		username = testuser
	}

	claims := &kitekey.KiteClaims{
		StandardClaims: jwt.StandardClaims{
			Issuer:   "testuser",
			Subject:  username,
			Audience: hostname,
			IssuedAt: time.Now().UTC().Unix(),
			Id:       tknID.String(),
		},
		KontrolKey: public,
		KontrolURL: "http://localhost:4000/kite",
	}

	token := jwt.NewWithClaims(jwt.GetSigningMethod("RS256"), claims)

	rsaPrivate, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(private))
	if err != nil {
		panic(err)
	}

	token.Raw, err = token.SignedString(rsaPrivate)
	if err != nil {
		panic(err)
	}

	// verify the token
	_, err = jwt.ParseWithClaims(token.Raw, claims, func(*jwt.Token) (interface{}, error) {
		return jwt.ParseRSAPublicKeyFromPEM([]byte(public))
	})

	if err != nil {
		panic(err)
	}

	token.Valid = true
	return token

}
Пример #2
0
// Verify a JWT token using an RSA public key
func VerifyJWTRSA(token, publicKey string) (bool, *jwt.Token, error) {

	var parsedToken *jwt.Token

	// parse token
	state, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {

		// ensure signing method is correct
		if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
			return nil, errors.New("unknown signing method")
		}

		parsedToken = token

		// verify
		key, err := jwt.ParseRSAPublicKeyFromPEM([]byte(publicKey))
		if err != nil {
			return nil, err
		}

		return key, nil
	})

	if err != nil {
		return false, &jwt.Token{}, err
	}

	if !state.Valid {
		return false, &jwt.Token{}, errors.New("invalid jwt token")
	}

	return true, parsedToken, nil
}
Пример #3
0
func InitTokens() (err error) {
	signBytes, err := ioutil.ReadFile("config/rsaKey")
	if err != nil {
		log.Error("Error reading private key from file: ", err)
		return
	}

	signKey, err = jwt.ParseRSAPrivateKeyFromPEM(signBytes)
	if err != nil {
		log.Error("Error parsing private key from file: ", err)
		return
	}

	verifyBytes, err := ioutil.ReadFile("config/pubKey")
	if err != nil {
		log.Error("Error reading public key from file: ", err)
		return
	}

	verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes)
	if err != nil {
		log.Error("Error parsing public key from file: ", err)
		return
	}
	return
}
Пример #4
0
func GetPublicKeyFromPath(path string) *rsa.PublicKey {
	bytes, err := ioutil.ReadFile(path)
	if err != nil {
		log.Fatal(err)
	}
	key, err := jwt.ParseRSAPublicKeyFromPEM(bytes)
	if err != nil {
		log.Fatal(err)
	}
	return key
}
Пример #5
0
// ReadPublicKey is a helper function for reading an rsa.PublicKey from a PEM-encoded file
// Reads public keys from both public and private key files
func ReadPublicKey(file string) (*rsa.PublicKey, error) {
	data, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, err
	}

	if privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(data); err == nil {
		return &privateKey.PublicKey, nil
	}

	return jwt.ParseRSAPublicKeyFromPEM(data)
}
Пример #6
0
func init() {
	signBytes, err := ioutil.ReadFile(privKeyPath)
	fatal(err)

	signKey, err = jwt.ParseRSAPrivateKeyFromPEM(signBytes)
	fatal(err)

	verifyBytes, err := ioutil.ReadFile(pubKeyPath)
	fatal(err)

	verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes)
	fatal(err)
}
Пример #7
0
func ParseTestPublicKey() interface{} {
	keyBytes, err := ioutil.ReadFile("../test_utils/public.pem")
	if err != nil {
		log.Fatal("Failed to parse public key.", err)
	}

	publicKey, err := jwt.ParseRSAPublicKeyFromPEM(keyBytes)
	if err != nil {
		log.Fatal("Failed to parse public key.", err)
	}

	return publicKey

}
Пример #8
0
// ReadPublicKeyFromPEM is a helper function for reading an rsa.PublicKey or ecdsa.PublicKey from a PEM-encoded byte array.
// Reads public keys from both public and private key files.
func ReadPublicKeyFromPEM(data []byte) (interface{}, error) {
	if privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(data); err == nil {
		return &privateKey.PublicKey, nil
	}
	if publicKey, err := jwt.ParseRSAPublicKeyFromPEM(data); err == nil {
		return publicKey, nil
	}

	if privateKey, err := jwt.ParseECPrivateKeyFromPEM(data); err == nil {
		return &privateKey.PublicKey, nil
	}
	if publicKey, err := jwt.ParseECPublicKeyFromPEM(data); err == nil {
		return publicKey, nil
	}
	return nil, fmt.Errorf("data does not contain a valid RSA or ECDSA key")
}
Пример #9
0
// KeyPair looks up a key pair that was used to sign Kontrol's kite key.
//
// The value is cached on first call of the function.
func (k *Kontrol) KeyPair() (pair *KeyPair, err error) {
	if k.selfKeyPair != nil {
		return k.selfKeyPair, nil
	}

	kiteKey := k.Kite.KiteKey()

	if kiteKey == "" || len(k.lastPublic) == 0 {
		return nil, errNoSelfKeyPair
	}

	keyIndex := -1

	me := new(multiError)

	for i := range k.lastPublic {
		ri := len(k.lastPublic) - i - 1

		keyFn := func(token *jwt.Token) (interface{}, error) {
			if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
				return nil, errors.New("invalid signing method")
			}

			return jwt.ParseRSAPublicKeyFromPEM([]byte(k.lastPublic[ri]))
		}

		if _, err := jwt.ParseWithClaims(kiteKey, &kitekey.KiteClaims{}, keyFn); err != nil {
			me.err = append(me.err, err)
			continue
		}

		keyIndex = ri
		break
	}

	if keyIndex == -1 {
		return nil, fmt.Errorf("no matching self key pair found: %s", me)
	}

	k.selfKeyPair = &KeyPair{
		ID:      k.lastIDs[keyIndex],
		Public:  k.lastPublic[keyIndex],
		Private: k.lastPrivate[keyIndex],
	}

	return k.selfKeyPair, nil
}
Пример #10
0
func init() {
	signBytes, err := ioutil.ReadFile(config.Settings.PrivKeyPath)
	if err != nil {
		logger.Log("Reading private Key File "+config.Settings.PrivKeyPath+" failed, Error: "+err.Error(), logger.ERROR)
	}

	signKey, err = jwt.ParseRSAPrivateKeyFromPEM(signBytes)
	if err != nil {
		logger.Log("Parsing private Key File failed, Error: "+err.Error(), logger.ERROR)
	}

	verifyBytes, err := ioutil.ReadFile(config.Settings.PubKeyPath)
	if err != nil {
		logger.Log("Reading public Key File "+config.Settings.PubKeyPath+" failed, Error: "+err.Error(), logger.ERROR)
	}

	verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes)
	if err != nil {
		logger.Log("Parsing public Key File failed, Error: "+err.Error(), logger.ERROR)
	}
}
Пример #11
0
func generateKeyExtractionFunctionForJTWFlow(applicationRepo roll.ApplicationRepo) jwt.Keyfunc {
	return func(token *jwt.Token) (interface{}, error) {
		//Check the signing method
		if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
		}

		//The aud claim conveys the intended application the token is used to gain access to.
		clientID := token.Claims["aud"]
		if clientID == nil {
			return nil, errors.New("Foreign token does not include aud claim")
		}

		//Look up the application
		app, err := applicationRepo.SystemRetrieveApplicationByJWTFlowAudience(clientID.(string))
		if err != nil {
			log.Info("Error looking up app for ", clientID, " ", err.Error())
			return nil, err
		}

		if app == nil {
			log.Info("No app definition associated with audience found: ", clientID.(string))
			return nil, errors.New("No app definition associated with aud found")
		}

		//We also check that the token was issued by the entity registered with the application
		issuer := token.Claims["iss"]
		if issuer == nil || issuer != app.JWTFlowIssuer {
			return nil, errors.New("Foreign token issuer not known")
		}

		//Grab the public key from the app definition
		keystring := app.JWTFlowPublicKey

		log.Info("validating with '", keystring, "'")

		//Parse the keystring
		return jwt.ParseRSAPublicKeyFromPEM([]byte(keystring))
	}
}
Пример #12
0
// ReadPublicKeysFromPEM is a helper function for reading an array of rsa.PublicKey or ecdsa.PublicKey from a PEM-encoded byte array.
// Reads public keys from both public and private key files.
func ReadPublicKeysFromPEM(data []byte) ([]interface{}, error) {
	var block *pem.Block
	keys := []interface{}{}
	for {
		// read the next block
		block, data = pem.Decode(data)
		if block == nil {
			break
		}

		// get PEM bytes for just this block
		blockData := pem.EncodeToMemory(block)
		if privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(blockData); err == nil {
			keys = append(keys, &privateKey.PublicKey)
			continue
		}
		if publicKey, err := jwt.ParseRSAPublicKeyFromPEM(blockData); err == nil {
			keys = append(keys, publicKey)
			continue
		}

		if privateKey, err := jwt.ParseECPrivateKeyFromPEM(blockData); err == nil {
			keys = append(keys, &privateKey.PublicKey)
			continue
		}
		if publicKey, err := jwt.ParseECPublicKeyFromPEM(blockData); err == nil {
			keys = append(keys, publicKey)
			continue
		}

		// tolerate non-key PEM blocks for backwards compatibility
		// originally, only the first PEM block was parsed and expected to be a key block
	}

	if len(keys) == 0 {
		return nil, fmt.Errorf("data does not contain a valid RSA or ECDSA key")
	}
	return keys, nil
}
Пример #13
0
func (k *Kite) updateAuth(reg *protocol.RegisterResult) {
	k.configMu.Lock()
	defer k.configMu.Unlock()

	switch {
	case reg.KiteKey != "":
		k.Config.KiteKey = reg.KiteKey

		ex := &kitekey.Extractor{
			Claims: &kitekey.KiteClaims{},
		}

		if _, err := jwt.ParseWithClaims(reg.KiteKey, ex.Claims, ex.Extract); err != nil {
			k.Log.Error("auth update: unable to extract kontrol key: %s", err)

			break
		}

		if ex.Claims.KontrolKey != "" {
			reg.PublicKey = ex.Claims.KontrolKey
		}
	}

	// we also received a new public key (means the old one was invalidated).
	// Use it now.
	if reg.PublicKey != "" {
		k.Config.KontrolKey = reg.PublicKey

		key, err := jwt.ParseRSAPublicKeyFromPEM([]byte(reg.PublicKey))
		if err != nil {
			k.Log.Error("auth update: unable to update kontrol key: %s", err)

			return
		}

		k.kontrolKey = key
	}
}
Пример #14
0
func NewAuthResource(privateKeyPath, publicKeyPath string, tokenDuration time.Duration, validator AuthValidator) *AuthResource {
	verifyBytes, err := ioutil.ReadFile(publicKeyPath)
	fatal(err)

	verifyKey, err := jwt.ParseRSAPublicKeyFromPEM(verifyBytes)
	fatal(err)

	signBytes, err := ioutil.ReadFile(privateKeyPath)
	fatal(err)

	signKey, err := jwt.ParseRSAPrivateKeyFromPEM(signBytes)
	fatal(err)

	if tokenDuration < 1 {
		tokenDuration = DEFAULT_TOKEN_DURATION
	}

	if nil == validator {
		validator = DummyAuthValidator
	}

	return &AuthResource{verifyKey, signKey, tokenDuration, validator}
}
Пример #15
0
func TestJWTToken(t *testing.T) {
	var err error
	var privateKeyContent, publicKeyContent []byte
	if privateKeyContent, err = ioutil.ReadFile("jwt-test.key"); err != nil {
		t.Fatal(err)
	}
	if publicKeyContent, err = ioutil.ReadFile("jwt-test.pub"); err != nil {
		t.Fatal(err)
	}
	if privateKey, err = jwt.ParseRSAPrivateKeyFromPEM(privateKeyContent); err != nil {
		t.Fatal(err)
	}
	if publicKey, err = jwt.ParseRSAPublicKeyFromPEM(publicKeyContent); err != nil {
		t.Fatal(err)
	}
	token := jwt.New(jwt.GetSigningMethod("RS256"))
	token.Claims = jwt.MapClaims{
		"PERMISSION": "admin@tiedot",
		"exp":        time.Now().Add(time.Hour * 72).Unix(),
	}
	ts, err := token.SignedString(privateKey)
	if err != nil {
		t.Fatal(err)
	}
	if token, err = jwt.Parse(ts, func(ts *jwt.Token) (interface{}, error) {
		return publicKey, nil
	}); err != nil {
		t.Fatal(err)
	}
	if token.Valid {
		t.Log(token)
	} else {
		t.Log(token)
		t.Fail()
	}
}
Пример #16
0
// Callback handles the callback from the user after the identity provider provided a code to the users agent
func (o *Google) Callback(w http.ResponseWriter, r *http.Request) (user map[string]string, err error) {
	// Delete CSRF Tokens afterwards
	defer func() {
		session, _ := o.SessionStore.Get(r, "goidc")
		delete(session.Values, "nonce")
		delete(session.Values, "state")
		session.Save(r, w)
	}()
	session, _ := o.SessionStore.Get(r, "goidc")
	oidcState, ok := session.Values["state"].(string)
	if !ok {
		return nil, fmt.Errorf("Session 'state' not found")
	}
	oidcNonce, ok := session.Values["nonce"].(string)
	if !ok {
		return nil, fmt.Errorf("Session 'nonce' not found")
	}

	err = r.ParseForm()
	if err != nil {
		return nil, fmt.Errorf("Could not parse form: %s", err)
	}
	code := r.Form.Get("code")
	if code == "" {
		return nil, fmt.Errorf("Did not receive code")
	}

	// CSRF Prevention using state
	if state := r.Form.Get("state"); state != oidcState {
		return nil, fmt.Errorf("Could not verify CSRF Token 'state': want: %s, got %s", oidcState, state)
	}
	vals := url.Values{}
	vals.Add("code", code)
	vals.Add("redirect_uri", o.RedirectURI)
	vals.Add("client_id", o.ClientID)
	vals.Add("client_secret", o.ClientSecret)
	vals.Add("grant_type", "authorization_code")
	c := http.Client{}

	// Exchange code for token
	req, err := http.NewRequest("POST", "https://www.googleapis.com/oauth2/v4/token", strings.NewReader(vals.Encode()))
	if err != nil {
		return nil, fmt.Errorf("Could not build request: %s", err)
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	resp, err := c.Do(req)
	if err != nil {
		return nil, fmt.Errorf("Error on token exchange request: %s", err)
	}
	var respValues map[string]interface{}
	dec := json.NewDecoder(resp.Body)
	err = dec.Decode(&respValues)
	if err != nil {
		return nil, fmt.Errorf("Error decoding token exchange resp to json: %s", err)
	}
	if _, ok := respValues["error"]; ok {
		return nil, fmt.Errorf("Error returned by the api: %v", respValues)
	}
	var idToken string
	idToken, _ = (respValues["id_token"]).(string)
	if idToken == "" {
		return nil, fmt.Errorf("No id token received: %#v", respValues)
	}

	// Check JWT using google certificates
	keyResp, err := http.Get("https://www.googleapis.com/oauth2/v1/certs")
	if err != nil {
		return nil, fmt.Errorf("Could not get keys from server: %s", err)
	}
	keyDec := json.NewDecoder(keyResp.Body)
	defer keyResp.Body.Close()
	var googleKeys map[string]string
	err = keyDec.Decode(&googleKeys)
	if err != nil {
		return nil, fmt.Errorf("Error decoding certificates from json: %s", err)
	}
	keylookup := func(kid string) (string, error) {
		for key, val := range googleKeys {
			if key == kid {
				return val, nil
			}
		}
		return "", fmt.Errorf("Could not find public key for kid: %s", kid)
	}

	// JWT - Verification including signing method
	token, err := jwt.Parse(idToken, func(token *jwt.Token) (interface{}, error) {
		if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
			return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
		}
		kid, ok := (token.Header["kid"]).(string)
		if !ok {
			return nil, fmt.Errorf("Key id not found")
		}
		key, err := keylookup(kid)
		if err != nil {
			return nil, err
		}
		return jwt.ParseRSAPublicKeyFromPEM([]byte(key))
	})

	// JWT Successfull
	if token.Valid {

		// CSRF Prevention using nonce
		nonce, ok := (token.Claims["nonce"]).(string)
		if !ok {
			return nil, fmt.Errorf("No nonce in claims: %v", token.Claims)
		}

		if nonce != oidcNonce {
			return nil, fmt.Errorf("Could not verify CSRF Token 'nonce': want: %s, got %s", oidcNonce, nonce)
		}
		// Verify token audience
		aud, ok := (token.Claims["aud"]).(string)
		if !ok {
			return nil, fmt.Errorf("No aud in claims: %v", token.Claims)
		}
		if aud != o.ClientID {
			return nil, fmt.Errorf("Verification of token 'audience' failed: %v", token.Claims)
		}

		user = make(map[string]string)

		// Check 'sub'
		uid, ok := (token.Claims["sub"]).(string)
		if !ok {
			return nil, fmt.Errorf("Could not get a unique user id")
		}
		user["id"] = uid
		name, ok := (token.Claims["name"]).(string)
		if !ok {
			return nil, fmt.Errorf("Could not get the name of the user")
		}
		user["name"] = name
		return user, nil
	} else if ve, ok := err.(*jwt.ValidationError); ok {
		if ve.Errors&jwt.ValidationErrorMalformed != 0 {
			return nil, fmt.Errorf("ID Token is malformed")
		} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
			return nil, fmt.Errorf("ID Token is expired or not active yet: %s", err)
		}
		return nil, fmt.Errorf("Could not handle ID Token: %s", err)
	}
	return nil, fmt.Errorf("Could not handle ID Token: %s", err)
}
Пример #17
0
UCosMSEAD909MAsyQWB4X6OJKd+V68QpFYeIx7UCgYBHgaRY6PYOBU92He36abLE
MVFZBKrRMtt0s0yHgGV/SxA6wXxCMAzFdaw7IqZBbWgPiwjZET6nxLFNsLVItFIK
5h44k6mVss5xuNTdUM+i+/S8tCZW964EMkMfKHmE1XFmTuBYqY6/D4b/7hBeAFeH
3f0hQr3ZFYa5Zao4UIZKvwKBgGL8lhUBt8lENVlhEYIpLfeJfomw6AxqfAfN1GzV
zpyMxX9DQqz1ZrhnvzgtwHcoqHda6/c+TgzVfBhRDw12A4f+ulvE8HupuIw4NoHS
g8jc3+O5uoYuUnfbnRJyOsPtb4VSLgXz6deUmI9fugmU1l55tH93jMT4ijyzg2BJ
grGxAoGAWX24Yx9qoasqEQ2rgdTsgylwL28UczKQ5KNHt2PcEfPNw6/GpfK7YmlU
Heef2umEzb1K2ZK95wlMbF8zpNDWBf4PkxgfW+JEE+pO1kb5KXysBymymyXhGHAP
CwH9XHqbjVlsD358AbPeKqLgTCaGo9JgsEZDBpESmBDnIPUahMc=
-----END RSA PRIVATE KEY-----`))

var rsaPubKey1, _ = jwtpkg.ParseRSAPublicKeyFromPEM([]byte(`-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArZIJcPQd7aSGb80wgFpy
5SVjzzsGpfIysZ30SdWlTcWMVbATXmsDNgw98TzIeoyikSbSHEeORbKWKS2clgNs
dLjYKv3XLTBaXfLcU3x9mhnk/kULN/AQgyvsRGynPris2oVzGSib7uOZK/9+u+QA
KIrp7prcmMmnwvdcjFXjwzx83RTF1b+iuVGCdV0T4m1XQdm/YtIUh7JNbYrUolkd
wZlOxMZuV0FDC+ms02+gyj580PylTuAD4JmtSmmijyWfEx5dsZYtGALyUxcm5Hz1
5RP3FACrv4B++BHI6smO4sWdrSYVl3sHJ60Bm6zbwuyB2twJPOdL5nVIGiIDdf+1
IwIDAQAB
-----END PUBLIC KEY-----`))

var rsaKey2, _ = jwtpkg.ParseRSAPrivateKeyFromPEM([]byte(`-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA4jr/DGbPt0UDGvu6Xo2LV0F6Wf8OnyxF2IFPdG5B4X0YS3DC
9SF3clbbBivDVa2bEXppyj+eLEKlfohCWXTrJK0LxTEcneuDkF4re+BdP3q9cKRz
FtI/ZVhVnD7+PS1wps7OiTM0iOaIDo9+uFrC6zBTRAiPyrdwh1ApttLdoD6i5D9D
7zzvpTXLC/UWaRz/phAaaop6dPPR1YblZEckWgqTMC3KrRX/6QJFFfpgyQzFT09W
DYnmXl2gS7C2sk4UejygqmVg96JxaIaT3WiQSjxXddjR/krcA9EGNNEkpZB2W6Ux
6d63yWsNG9YJUacwI+M2q5ZW964J1s//FiNZZQIDAQABAoIBAQCoqYtU16Gs5Qq3
p0z/CVAFMY/iYMGp8fvwuhdemoULc5QVSnBPCTBgUljgdOggjFm74iPU4TEvllCD
0VqGDyDwKwNHdKH9KoTfsRWCOXfLx9pMjI4xSXZyPDU3U8+AFMyT0EMzDrXwCs8M
6/Zxw1jmtxSc+DUb0T9X4m/3GaaZvDGGShnU8/XnEh2uEHrNwWnGWYPJ/rZjNZPy
Пример #18
0
// ParsePublicKey parses a []byte representation of a public key into a rsa.PublicKey instance
func ParsePublicKey(key []byte) (*rsa.PublicKey, error) {
	return jwt.ParseRSAPublicKeyFromPEM(key)
}
Пример #19
0
// UnauthorizeCreateUpdateDeleteTest will check authorized access to Create/Update/Delete APIs
func UnauthorizeCreateUpdateDeleteTest(t *testing.T, getDataFunc func(t *testing.T) []testSecureAPI, createServiceFunc func() *goa.Service, mountCtrlFunc func(service *goa.Service) error) {
	resource.Require(t, resource.Database)

	// This will be modified after merge PR for "Viper Environment configurations"
	publickey, err := jwt.ParseRSAPublicKeyFromPEM([]byte(almtoken.RSAPublicKey))
	if err != nil {
		t.Fatal("Could not parse Key ", err)
	}
	tokenTests := getDataFunc(t)

	for _, testObject := range tokenTests {
		// Build a request
		var req *http.Request
		var err error
		if testObject.payload == nil {
			req, err = http.NewRequest(testObject.method, testObject.url, nil)
		} else {
			req, err = http.NewRequest(testObject.method, testObject.url, testObject.payload)
		}
		// req, err := http.NewRequest(testObject.method, testObject.url, testObject.payload)
		if err != nil {
			t.Fatal("could not create a HTTP request")
		}
		// Add Authorization Header
		req.Header.Add("Authorization", testObject.jwtToken)

		rr := httptest.NewRecorder()

		service := createServiceFunc()
		require.NotNil(t, service)

		// if error is thrown during request processing, it will be caught by ErrorHandler middleware
		// this will put error code, status, details in recorder object.
		// e.g> {"id":"AL6spYb2","code":"jwt_security_error","status":401,"detail":"JWT validation failed: crypto/rsa: verification error"}
		//service.Use(middleware.ErrorHandler(service, true))
		// e.g. > {"errors":[{"code":"unknown_error","detail":"[19v4Bp8f] 401 jwt_security_error: JWT validation failed: Token is expired","status":"401","title":"Unauthorized"}]}
		service.Use(jsonapi.ErrorHandler(service, true))

		// append a middleware to service. Use appropriate RSA keys
		jwtMiddleware := goajwt.New(publickey, nil, app.NewJWTSecurity())
		// Adding middleware via "app" is important
		// Because it will check the design and accordingly apply the middleware if mentioned in design
		// But if I use `service.Use(jwtMiddleware)` then middleware is applied for all the requests (without checking design)
		app.UseJWTMiddleware(service, jwtMiddleware)

		if err := mountCtrlFunc(service); err != nil {
			t.Fatalf("Failed to mount controller: %s", err.Error())
		}

		// Hit the service with own request
		service.Mux.ServeHTTP(rr, req)

		require.Equal(t, testObject.expectedStatusCode, rr.Code, testObject.String())

		// Below code tries to open Body response which is expected to be a JSON
		// If could not parse it correctly into app.JSONAPIErrors
		// Then it gets logged and continue the test loop
		//fmt.Printf("\nrr.Body = %s\n", string(rr.Body.Bytes()))
		jerrors := app.JSONAPIErrors{}
		err = json.Unmarshal(rr.Body.Bytes(), &jerrors)
		if err != nil {
			t.Log("Could not parse JSON response: ", rr.Body)
			// safe to continue because we alread checked rr.Code=required_value
			continue
		}
		// Additional checks for 'more' confirmation
		require.Equal(t, testObject.expectedErrorCode, *jerrors.Errors[0].Code)
		require.Equal(t, strconv.Itoa(testObject.expectedStatusCode), *jerrors.Errors[0].Status, testObject.String())
	}
}