github.com/dbernstein1/tyk@v2.9.0-beta9-dl-apic+incompatible/gateway/mw_oauth2_key_exists.go (about) 1 package gateway 2 3 import ( 4 "errors" 5 "net/http" 6 "strings" 7 "time" 8 9 "github.com/TykTechnologies/tyk/apidef" 10 "github.com/TykTechnologies/tyk/headers" 11 ) 12 13 const ( 14 checkOAuthClientDeletedInetrval = 1 * time.Second 15 ) 16 17 // Oauth2KeyExists will check if the key being used to access the API is in the request data, 18 // and then if the key is in the storage engine 19 type Oauth2KeyExists struct { 20 BaseMiddleware 21 } 22 23 func (k *Oauth2KeyExists) Name() string { 24 return "Oauth2KeyExists" 25 } 26 27 func (k *Oauth2KeyExists) EnabledForSpec() bool { 28 return k.Spec.UseOauth2 29 } 30 31 // ProcessRequest will run any checks on the request on the way through the system, return an error to have the chain fail 32 func (k *Oauth2KeyExists) ProcessRequest(w http.ResponseWriter, r *http.Request, _ interface{}) (error, int) { 33 logger := k.Logger() 34 // We're using OAuth, start checking for access keys 35 token := r.Header.Get(headers.Authorization) 36 parts := strings.Split(token, " ") 37 38 if len(parts) < 2 { 39 logger.Info("Attempted access with malformed header, no auth header found.") 40 41 return errors.New("Authorization field missing"), http.StatusBadRequest 42 } 43 44 if strings.ToLower(parts[0]) != "bearer" { 45 logger.Info("Bearer token malformed") 46 47 return errors.New("Bearer token malformed"), http.StatusBadRequest 48 } 49 50 accessToken := parts[1] 51 logger = logger.WithField("key", obfuscateKey(accessToken)) 52 53 // get session for the given oauth token 54 session, keyExists := k.CheckSessionAndIdentityForValidKey(accessToken, r) 55 if !keyExists { 56 logger.Warning("Attempted access with non-existent key.") 57 58 // Fire Authfailed Event 59 AuthFailed(k, r, accessToken) 60 // Report in health check 61 reportHealthValue(k.Spec, KeyFailure, "-1") 62 63 return errors.New("Key not authorised"), http.StatusForbidden 64 } 65 66 // Make sure OAuth-client is still present 67 oauthClientDeletedKey := "oauth-del-" + k.Spec.APIID + session.OauthClientID 68 oauthClientDeleted := false 69 // check if that oauth client was deleted with using memory cache first 70 if val, found := UtilCache.Get(oauthClientDeletedKey); found { 71 oauthClientDeleted = val.(bool) 72 } else { 73 // if not cached in memory then hit Redis to get oauth-client from there 74 if _, err := k.Spec.OAuthManager.OsinServer.Storage.GetClient(session.OauthClientID); err != nil { 75 // set this oauth client as deleted in memory cache forever 76 UtilCache.Set(oauthClientDeletedKey, true, -1) 77 oauthClientDeleted = true 78 } else { 79 // set this oauth client as NOT deleted in memory cache for next N sec 80 UtilCache.Set(oauthClientDeletedKey, false, checkOAuthClientDeletedInetrval) 81 } 82 } 83 if oauthClientDeleted { 84 logger.WithField("oauthClientID", session.OauthClientID).Warning("Attempted access for deleted OAuth client.") 85 return errors.New("Key not authorised. OAuth client access was revoked"), http.StatusForbidden 86 } 87 88 // Set session state on context, we will need it later 89 switch k.Spec.BaseIdentityProvidedBy { 90 case apidef.OAuthKey, apidef.UnsetAuth: 91 ctxSetSession(r, &session, accessToken, false) 92 } 93 94 // Request is valid, carry on 95 return nil, http.StatusOK 96 }