Code Monkey home page Code Monkey logo

microgateway-plugins's Introduction

Plugins

Overview

This repo contains plugins for the microgateway-core project.

These plugins can be loaded into the microgateway calling the load plugin method

Building a plugin

must contain an init method which returns an object literal with all of the handlers

{
  init:function(config,logger,stats){
    return {
    onrequest:function(req,res,[options],next){
    },
    ...
    }
  }
}

init method must return an object with handler methods for each event

the available handlers are

  • on_request
  • ondata_request
  • onend_request
  • on_response
  • ondata_response
  • onend_response
  • onclose_response
  • onerror_response

The handler signature will look like :

function(sourceRequest,sourceResponse,[options],next){}
  • sourceRequest: the request from the northbound server;

  • sourceResponse the response to the northbound server;

  • options: are the full scope of fields you might need to operate on.

    	const options = {
        targetResponse: options.targetResponse,
        targetRequest: options.targetRequest,
        sourceRequest: options.sourceRequest,
        sourceResponse: options.sourceResponse,
        data: data
      };
  • you must call next with an error if you errored out like

next([err])

microgateway-plugins's People

Contributors

dependabot[bot] avatar dkoroth avatar erickbelfy avatar f1erro avatar fpavageau avatar gaonkar18y avatar imesh avatar indraneeldey avatar kevinswiber avatar keyurkarnik avatar kylewiese avatar mdobson avatar mitchfierro avatar niheelthakkar89 avatar philschleier avatar pjherz avatar prapunjt avatar rleddy avatar shawnfeldman avatar shiveshwar avatar shivintelli avatar srikanthbhadragiri avatar srinandan avatar srjohnjohnny avatar stx-cld avatar sudheesreedhara avatar swilliams11 avatar tapasthakkar avatar theganyo avatar vilobhmm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

microgateway-plugins's Issues

OAuth plugin does not grab key from JWK properly

The OAuth plugin in its current state fails to grab any valid JWK. The reason for this is that it evaluates the wrong property on the keys object. Here is the getJWK() function in its current state:

function getPEM(decodedToken, keys) {
    var i = 0;
    debug('jwk kid ' + decodedToken.headerObj.kid);
    for (; i < keys.length; i++) {
        if (keys.kid == decodedToken.headerObj.kid) {
            break;
        }
    }
    var publickey = rs.KEYUTIL.getKey(keys.keys[i]);
    return rs.KEYUTIL.getPEM(publickey);
}

Note how this function tries iterating over keys at its root, and accessing keys.kid, but keys is not iterable at its root, nor does it have any properties apart from keys. The structure of keys is (in my case) as follows:

{
    "keys": [
        {
            "kty": "RSA",
            "alg": "RS256",
            "kid": "99gMqQi7UIfDqij_JX_RoNkC-bU-vlGQGwXoKWbGoes",
            "use": "sig",
            "e": "AQAB",
            "n": "gDf_fZFQrmZw14aHvJWb2SaQ30XBzYqu40SRFBgGGg-2TGRJD5rKbehPWGfZpYw2UEp2-aYw2-pFzAJF4SfFo3IjsU2tM5kEFCUreJdDW0II7ZaGaxXFcyteX7ULGErdZkX8w98Zay8abOegJpsDr8UBgJ0wNIpXx_nEe_ttrj3XexJ9ximJkrHvg4X9_mYhghOO5BbernrjEkeZo1ioQj4Q_H-Cn-DUwODr9b6NJ46qvo1UrKij13Q4lNNftUgvRQy0wNCUUNNgAZpVJOruMS9DUdCv5MGjgVsW7_KLHfUj0-di19XSRrQHyK_wh22gqzUoPaj-rVmqzQ1itkELWw"
        },
        {
            "kty": "RSA",
            "alg": "RS256",
            "kid": "luIheUMdlhacSF0zk2-tNDA7qd3sns_l21arS59FX-8",
            "use": "sig",
            "e": "AQAB",
            "n": "xh8tmPpzytiEfmBOn1oA20hH2TSLTcRdZprXK4tKuWnhiBz__E_qGusFf8lAA9tN9BZM_YptLRd6fjKjbRv1D8XUEqgwQoUVI9oNK-WvaZL0ZT1AIzbP5wUN-5uxOhwczp-nQ_R7IYjED_v1snHQRNf4W-8295UzjdHwTr29cw2wdLDsnSvgtwpHd9zpcCXaFkQ6-g9M8OariL0jL7KPCUSpb1e9E-Swmq6af2E8Peq9B68Ecys2Jf1iw24oIncS-vg9ZGuq4F5MASKmLVDjbBIrU2lQ3muK6JrakKQYxqVMnaS6vR-U3bEp7CcuGo-sfRZTZT6RYusJSy2GNLutYw"
        }
    ]
}

Thus, the function should iterate over keys.keys, or keys should be populated by the keys object in this JSON object.

I've already submitted a PR that resolves this issue, and adds support for situations like https://www.googleapis.com/oauth2/v1/certs . This PR can be found here: #87

accesscontrol plugin allows IPs that are NOT in the allow list.

If you send a request from an IP address and that IP is not listed in the allow list, then this plugin still allows the request to continue. It should fail in this instance.

Can we update this plugin, lines 24 - 26, as shown below?
https://github.com/apigee/microgateway-plugins/blob/master/accesscontrol/index.js#L24

if (scanIP(config.allow, sourceIP)) {
allow = true;
} else {
allow = false;
}

We should also update lines 30 - 33 as shown below.
https://github.com/apigee/microgateway-plugins/blob/master/accesscontrol/index.js#L30

if (scanIP(config.deny, sourceIP)) {
debug ('deny incoming message');
deny = true;
} else {
deny = false;
}

ExAuth Plugin EM is Unable to extract Client ID from JWT

The plugin notes stated that EM will extract the client_id from the JWT.
Sample Log :
2019-12-11T22:00:50.582Z plugin:extauth Found JWK
2019-12-11T22:00:50.590Z plugin:extauth JWT Expiry enabled
2019-12-11T22:00:50.631Z plugin:extauth JWT is valid
2019-12-11T22:00:50.632Z plugin:oauth missing_authorization
2019-12-11T22:00:50.632Z plugin:oauth auth failure 401 missing_authorization Missing Authorization header { 'user-agent': 'PostmanRuntime/7.19.0',

oauth plugin issue: allowAPIKeyOnly/allowOAuthOnly breaks allowNoAuthorization

AllowAPIKeyOnly and allowOAuthOnly are configuration flags that should restrain where to look for authorization details in an incoming request, i.e. headers "x-api-key" (for a consumer key) or "authorization" for an Apigee OAuth token.
allowNoAuthorization and allowInvalidautorization are used to specify if oauth plugin should return a 401 when the authentication details are missing (for the first flag) or invalid (second flag), or let the request go.
I believe the first two flags (where to get authN details from) should not impact the behavior of the second set of flags (what to do with the authN details). However, setting one of the two flags from the first set to true breaks the behavior of allowNoAuthorization. De facto, no matter what is the value of allowNoAuthorization, it behaves as if it's set to "false".

{"message":"Invalid value \"undefined\" for header \"Access-Control-Allow-Origin\""}

This exception gets generated when CORS plugin is enabled.

{"message":"Invalid value \"undefined\" for header \"Access-Control-Allow-Origin\""}

Perhaps these lines could be within a try and catch block. https://github.com/apigee/microgateway-plugins/blob/master/cors/index.js#L20

	  if(req.method == 'OPTIONS') {
	    res.setHeader('Access-Control-Allow-Origin', accessControlAllowOriginValue);
	    res.setHeader('Access-Control-Allow-Methods', methods);
       	    res.setHeader('Access-Control-Allow-Max-Age', maxAge);
	    res.setHeader('Access-Control-Allow-Headers', allowHeaders);
	    res.end();
	  } else {
        res.setHeader('Access-Control-Allow-Origin', accessControlAllowOriginValue);
	    next();
	  }

json2xml plugin incorrectly changes request 'content-length' header

Lines #137 and #141

The request object has all header names in lower case, but the code uses Capital case.

req.headers['Content-Type'] = ...

This will result in the same header being appended. I.e. it ends up with 'Content-Type' and 'content-type'.
The fix should be to assign the header using the lower-case name.

n.b. setHeader(.., ..) method is not available on the IncomingRequest type.

json2xml plugin doesn't accumulate request when disabled

If disable !== false, the request handlers don't accumulate the request.

Therefore, when the plugin is disabled by the 'x-apigee-json2xml-disable' header, it results in the payload not being sent to the target server.

I don't think this is intentional. Disabling the plugin should simply not change any behaviour.

When it's disabled, it should still need to accumulate the request payload.

CORS plugin not executing properly

In microgateway, we have plugin sequence as

- cors
- oauth

Whenever options request reaches microgateway, the response headers are set and then the request is forwarding to oauth plugin which is wierd
As per this line it should end the options request right there. But it is being sent to next plugin

apikeys plugin - cacheKey: false does not disable apikey caching

There are two ways to disable API Key caching in EM:

  1. set the cacheKey equal to false in the EM config file
apikeys:
  cacheKey: false
  1. include the following request header.
Cache-Control: no-cache

The 2nd option works, but the first option does not work.

The cacheKey variable is set to false by default, so apikey caching should always be disabled. The reason it is enabled is because the cacheControl variable is "undefined" when there is no cache-control header and !cacheControl changes the value to true, which is why caching is always enabled.

                if (cacheKey || (!cacheControl || (cacheControl && cacheControl.indexOf("no-cache") < 0))) { 

We should update this code to remove the !cachedControl condition.

OAuth plugin checking for API Product List in invalid place

In my edgemicro instance, I'm using a JWK set to authorize my requests. I've fixed the issues with verification at #88 locally on my edgemicro instance using the code from #87 , but I still can't seem to get past authorization. After stepping through the oauth plugin's code manually, I see that the issue is with the checkIfAuthorized() function - at present, it's looking for decodedToken.api_product_list and denying requests that don't have that object. Because I'm using a third-party JWT and JWK set (Okta), my requests are being denied at this point for not having an api_product_list property. My first thought was that I should add a claim on my token to populate api_product_list in payloadObj, but that's not where the plugin is currently looking. Is this the intended approach? Is there supposed to be a fourth field apart from header, payload, and signature named api_product_list to authorize against, or is the oauth plugin code incorrect and the reference should be to decodedToken.payloadObj.api_product_list? If that's the case, I'm happy to resolve the issue myself and submit a PR with the fixed code. If not, how do I add an entire extra section to a JWT without violating standard JWT conventions?

Rewriting target URL in plugins not working

Follow the document of Rewriting URL in plugins, and sample eurekaclient, rewriting is broken for the following version
microgateway: 3.2.1
NodeJS: v14.17.0
in onrequest() overwriting req.targetHostname, req.targetPort, req.targetPath, req.targetSecure. The microproxy does not overwrite the URL deployed in edge.
Here are some logs:
gateway:main selected proxy https://api.example.com:443/wsdl with base path /v1/edgemicro_test for request path /v1/edgemicro_test
...
gateway:main targetRequest xxxxx GET https://api.example.com 443 /wsdl
...
plugin debug shows
req.targetHostname: test.example.com
req.targetPort: 443
req.targetSecure: true
req.tartetPath: /wsdl
...
gateway:main targetRequest error.... Hostname/IP does not match certificate ... Host: api.example.com...
which is the original target URL deployed in edge instead of the overwritten URL.

extauth plugin and api_product_list check in oauth plugin

I'm trying to config microgateway to accept a third party JWT via plugin extauth.

The request passes extauth plugin without issue but fails in oauth plugin with 403 error below:

  plugin:extauth plugin onrequest +17s
  plugin:extauth Found jwt kid: thejwtkid +1ms
  plugin:extauth Found JWK +0ms
  plugin:extauth JWT Expiry enabled +6ms
  plugin:extauth JWT is valid +45ms
  plugin:oauth validating jwt +0ms
  plugin:oauth product only: false +23ms
  plugin:oauth no api product list +0ms
  plugin:oauth** auth failure 403 access_denied  { host: 'host.domain.name',..}

What failed is the following check in oauth.checkIfAuthorized;

    if (!decodedToken.api_product_list) {
        debug('no api product list');
        return false;
    }

The oauth plugin is looking for api_product_list property in decoded JWT. Well, doesn't this defeat the purpose of using extauth plugin unless there is something wrong in my setup? That property won't exist in third party JWT.

Any suggestions?

Thanks

Memory leak starting with version 3.0.12

This refactoring between 3.0.11 and 3.0.12 introduced a memory leak, through the dynamic creation of debug instances. See debug-js/debug#678, and the possible fix currently waiting in debug-js/debug#740. This impacts apigee-internal/microgateway in version 3.1.0 and above.

A possible fix is to locally cache the debug instance created for each component, instead of creating a new one for each request.

It would also be possible to pass the existing debug instance instead of the component name as the parameter to checkIfAuthorized(), but I guess it's less abstract.

How to use monitor plugin?

Hi Team,

Was going through the monitor plugin and I would like more info/documentation on how to use it. Am running a custom build of the microgateway image.

Any pointers will be appreciated.

Regards,

Moses.

ApiKey caching is not using the cache expiry mechanism

[feature request]

In apikeys (and same code in oauth and oauthv2)

cache.store(apiKey, decodedToken);

A distinct expiration time is known but not passed to the cache. This could benefit

  • less IPC transfer for objects that are expired
  • simpler cache retrieval logic (memored already checks the TTL on retrieval)
  • proactively evicting stale JWTs from cache making room for more active apiKeys

[oauth] exclude uris

Is is possible bypass some urls match some patterns, e.g. we want bypass /healthcheck url

json2xml plugin not threadsafe

several variables are defined instance level which causes concurrency issues.

For example. if a request is disabled by 'x-apigee-json2xml-disable' header, disable=true will get set and thereon apply to all requests.

These variables should be scoped to the request object so that they only apply to the specific request thread.

Scope validation

It appears the oauth plugin does not validate scopes. The plugin has access to the scope information (in the access_token) and from /products. It should be relatively easy for the plugin to validate.

Ability to skip oauth plugin

Hi, we have a requirement to expose certain endpoints without apikey/oauth validation.
The validation of whether or not to skip a certain URL is not the issue, we can do that in a separate plugin. The question is how can we tell the oauth plugin to skip execution?

I propose introducing an attribute on the request (req.skip, for example) and adding a simple check if (req.skip) next() to the oauth plugin.

  1. is there another way to achieve this that I'm not seeing?
  2. can we get this into the oauth plugin as I can't just fork & rename the oauth plugin (because the injected plugin configuration is dependent on the plugin name)

Regards,
Philipp

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.