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