Code Monkey home page Code Monkey logo

krakend-jose's Introduction

krakend-jose

JOSE component for the KrakenD framework

krakend-jose's People

Contributors

alombarte avatar alyhkafoury avatar bcreaney avatar brunobastosg avatar cdennig avatar deepsource-autofix[bot] avatar deepsourcebot avatar dhontecillas avatar foxcool avatar kpacha avatar lwohlhart avatar mguay22 avatar michael2008s avatar nedopolz avatar neokeld avatar pirm-in avatar skyverr avatar taik0 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  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

krakend-jose's Issues

Roles_key only support parsing string list in claims

I have a JWT that has the current user role in a string and not in a list of strings like this:

{
  "user_info": {
    "accessType": "REGISTERED|IP,
    "accountId": ...,
  },

I set the roles_key to be user_info.accessType but it seems that the current implementation of roles_key only support a list of strings. Would it make sense to also support parsing it as a string if it's not a list?

Expiration time for token from krakend-jose/signer

I am using krakend-jose/signer for generating JWT as my backend is returning some basic info and no JWT and no expiration time as well. I am using the return value in payload. Now my queries are

  1. What is the expiry time of token generated from krakend-jose/signer and how can I change it?
  2. How can I generate refresh token?

Any help will be great. Thanks.

JWT Validator with scopes doesn't work

When I use the krakend-jose/validator plugins to validate JWT, everything works good except for the scopes validation.

JWT payloads

{
  "exp": 1626451594,
  "iat": 1626451294,
  "sub": "user id",
  "typ": "Bearer",
  "scope": "user-scope"
}

KrakenD Configs

"endpoints": [
    {
      "method": "GET",
      "endpoint": "/protect-endpoint",
      "headers_to_pass": [
        "*"
      ],
      "extra_config": {
        "github.com/devopsfaith/krakend-jose/validator": {
          "alg": "RS256",
          "jwk-url": "jwk.json",
          "scopes_key": "scope",
          "scopes": ["admin-scope"]
        }
      },
      "output_encoding": "no-op",
      "backend": []
    }
]

Although, the JWT payload does not have the matched scope as seen in the preceding payloads and config, the request is still valid and call to the backend endpoint, but my expectation is that it should be rejected with 401 Unauthorized.

Support signed cookies

As I understand, pull #2 only allow to use unsigned cookies. Is there a way to use signed ones?

Thanks.

Support for Space Delimited Scopes

Currently the JWT validator is unable to handle spec defined scope claims via the roles and roles-key configuration when they are space delimited.

Example:

{
  "user": "Test User",
  ...
  "scope": "orders refunds",
 ...
}

Signing fails silently if JWK is not reachable?

In my local testing using the 1.1.1 and 1 versions of the krakend docker container, the JOSE plugin appears to access the jwks-url once on startup. If it fails to download the JWK key object, then Kraken continues to serve content, but signing is skipped.

Given a simple signer configuration for a dummy /authn endpoint, based on the docs:

{
   "github.com/devopsfaith/krakend-jose/signer":{
      "alg":"HS256",
      "kid":"jwk",
      "keys-to-sign":[
         "access_token",
         "refresh_token"
      ],
      "jwk-url":"http://authmock:8080/jwk/symmetric.json",
      "disable_jwk_security":true
   }
}

If the authmock service is offline when I start Kraken, then I see these log messages:

[KRAKEND] 2020/03/25 - 14:37:20.803 ▶ ERROR Get "http://authmock:8080/jwk/symmetric.json": dial tcp 23.217.138.110:8080: connect: connection refused /authn
...
[KRAKEND] 2020/03/25 - 14:37:20.803 ▶ INFO JOSE: validator disabled for the endpoint /authn

Posting to /authn (based on the example from the docs), returns the content without signing the keys:

# curl -s -X POST --data '{ "user": "alice" }' http://kraken.local/authn
{
  "access_token": {
    "aud": "http://demo",
    "exp": 1616601217,
    "jti": "bb8ed933-0d2f-4c7c-b00c-75b978f0222e",
    "sub": "alice"
  },
  "exp": 1616601217,
  "refresh_token": {
    "aud": "http://demo",
    "exp": 1735689600,
    "jti": "de88cb24-e88f-4f1b-81e8-30d6d34cb897",
    "sub": "alice"
  }
}

This behavior persists even after launching the JWK service. When JOSE is able to reach the JWK url at startup, the access_token and refresh_token keys are signed as expected.

For the moment, I can use scripting/probes in our kubernetes deployments to mitigate this risk by waiting for JWKs availability prior to starting Kraken, and restarting it in the event of an ERROR log message, but it'd be nice if it were more resilient, e.g. with a backoff retry, to account for out-of-order service startups in kube deployments.

Alternatively, if we had the ability to specify a file URL, then I could use secret injection and ensure the resource was available at container start.

Minimally, I think that JOSE should refuse to serve the content--or be configured to refuse to serve the content--if it cannot apply the signing.

Bearer Token Validation - JWT HS256

Hello Krakend team:
I'm trying to run Krakend with Docker, with JWT middleware and I don't know what am I doing wrong for getting the following error:

Error #1: no Keys has been found"

This is my configuration file:

{
  "version": 2,
  "timeout": "3000ms",
  "cache_ttl": "300s",
  "host": [ "http://authentication:8081", "https://jsonplaceholder.typicode.com" ],
  "extra_config": {
    "github_com/devopsfaith/krakend-gologging": {
      "level":  "DEBUG",
      "prefix": "[KRAKEND]",
      "syslog": false,
      "stdout": true
    },
    "github_com/devopsfaith/krakend-cors": {
      "allow_origins": [],
      "allow_methods": [ "POST", "GET", "DELETE", "PUT", "OPTIONS" ],
      "allow_headers": ["Origin","Authorization","Content-Type", "Access-Control-Allow-Origin", "locale", "accept", "x-requested-with", "Cache-Control"],
      "expose_headers": ["Content-Length", "Content-Type", "Cache-Control", "Authorization"],
      "max_age": "12h",
      "allow_credentials": true
    }
  },
  "endpoints": [
    {
      "endpoint": "/api/authentication/login",
      "method": "POST",
      "backend": [
        {
          "host": [ "http://authentication:8081" ],
          "url_pattern": "/api/authentication/login"
        }
      ]
    },
    {
      "endpoint": "/protected/resource",
      "extra_config": {
          "github.com/devopsfaith/krakend-jose/validator": {
              "alg": "HS256",
              "jwk-url": "http://authentication:8081/jwk",
              "disable_jwk_security": true
          }
      },
      "backend": [
          {
            "host": "https://jsonplaceholder.typicode.com",
            "url_pattern": "/todos/1"
          }
      ]
    }
  ]
}

The endpoint that provides the jwk is returning this response when calling

http://authentication:8081/jwk

{
    "keys": [
        {
            "kty": "oct",
            "kid": "key1",
            "k": "1Aj0dBGu5OYigpE2-JAynzBy6hz7H3XpmIpJZiB0XUQ",
            "alg": "HS256"
        }
    ]
}

That same key is used to sign the JWT token that is sent on successfull login:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbGljZSIsImlzcyI6Imh0dHBzOlwvXC9jMmlkLmNvbSIsImV4cCI6MTU0MjkyNjc5N30.ksE9yj4R9GkWDS17fkskn45KQMA_zbQfhDxO7A-lQoA

When I call the protected resource I call with that same token:

GET /protected/resource HTTP/1.1
Host: localhost:8080
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhbGljZSIsImlzcyI6Imh0dHBzOlwvXC9jMmlkLmNvbSIsImV4cCI6MTU0MjkyNjc5N30.ksE9yj4R9GkWDS17fkskn45KQMA_zbQfhDxO7A-lQoA
cache-control: no-cache
Postman-Token: e8ffcc64-6500-4d4c-b628-2ce6837abbb4

And I allways get an Unauthorized response:

gateway_1_d11464d89157 | [GIN] 2018/11/22 - 22:47:04 | 401 |      9.8294ms |      172.25.0.1 | GET      /protected/resource
gateway_1_d11464d89157 | Error #01: no Keys has been found

Can you help me with this? Thanks.

JWT cache not shared across endpoints ?

Configured Krakend to cache JWKS keys:

    extra_config:
      github.com/devopsfaith/krakend-jose/validator:
        alg: RS256
        jwk-url: "http://myidp/jwks"
        issuer: "http://myidp"
        propagate-claims:
        - ["sub", "x-user"]
        disable_jwk_security: true # only for non https jwk-url
        cache: true
        cache_duration: 300

Although cache is enabled, we see multiple retrieval requests of JWKS from krakend host to the identity provider aka IDP. Tests are showing cache is effective but per end-point and every end-point loads its cache at startup.

As a consequence:

  1. we get as much requests as different endpoints every 15min (cache_duration fails to be effective, see my other issue)
  2. we get a bunch of JWKS requests each time a new Krakend running instance is started.
  3. this is putting extra load (and cost when hosted on pubic cloud providers) on our IDP and its front LB

Support for Firebase Auth API

Is there a complete support for Firebase Auth API for Krakend-jose (token validation)?

Usually, the clients will authenticate directly to firebase and gets a user token, and that token is sent to the backend. Then, the backend verifies that token through the firebase sdk (depends on the language used - in this case, Go). Is there a way to move this logic completely to krakend so all api requests are validated in the API gateway layer? How does krakend verify the token in firebase sdk?

I noticed it was mentioned in this documentation but there were no other documentation to achieve this step-by-step.

Configurable option to use CertificateThumbprintSHA1 instead of KeyID for JWK cache construction

Is your feature request related to a problem? Please describe.
An OAuth 2 authentication server has decided to implement the issuing of access token (JWT) and the issuing of JWK by using the same value in the kid field for both structures.

`
jwt
{
"wbaxrV5e7SwP979FZhipGL4grrzz6Huprgh8GhmYLXw",
"x5t": "h_qy14b0XfJGElJAqW2jjoEpzUc",
"kid": "KEY",
"alg": "RS256"...
}

jwk
{
"kty": "RSA",
"x5t#S256": "bD2Ba4uIs0lLNyZAg_4Fbs2PgjqsF3p9AA21_Xkye34",
"e": "AQAB",
"x5t": "-1VGrqVBZ-Cc2k21fMx5n9qv-xI",
"kid": "KEY",
"x5c": ...
`

My understanding of Krakend is as the following:
the jwk spec library (structure) https://godoc.org/gopkg.in/square/go-jose.v2#JSONWebKey
auth0 creating jwk cache https://github.com/auth0-community/auth0-go/blob/master/key_cacher.go#L67
krakend-jose utilizing jwk cache https://github.com/devopsfaith/krakend-jose/blob/master/jwk.go#L43

To resolve this issue, I would have to fork the auth0-go library, modify the jwk cache construction, change how Krakend-jose uses that package, and then maintain my own implementation.

Describe the solution you'd like
It appears that krakend-jose is only using the ADD and the GET of aut0-go library, be great if it provides an option to use x5t as the key of jwk cache and we can set it as part of extra_config.

Describe alternatives you've considered
Change how that specific auth server provides token, but that's proprietary, not open source.

Additional context

Support for multiple jwk-url based on different issuer

Hi there,

We have a specific scenario where we have external partners that will connect to our gateway in order to access our API set. Nevertheless, they will be in charge of managing their jwks, therefore, we would need to have different jwk URL per issuer. AFAIK, this is not supported today.

Initially I would imagine one options would be having different gateway instances per issuer. But our idea is to have only one Gateway cluster, therefore, I wonder if something like the proposed improvement to the validator configuration would be accepted by you.

I would be available to implement it and open a PR to you guys. For sure, we would keep it supporting both formats.

Hope to get a feedback from you or even if you guys think in a better alternative, I would appreciate it a lot.

config enhancement proposal

{
"endpoint": "/foo"
"extra_config": {
    "github.com/devopsfaith/krakend-jose/validator": {
      "issuer-1": {
        "alg": "RS256",
        "jwk-url": "https://url/to/jwks.json",
        "cache": true,
        "audience": [
            "audience1"
        ],
        "roles_key": "department",
        "roles_key_is_nested": false,
        "roles": [
            "sales",
            "development"
        ],
        "issuer": "http://my.api.com",
        "cookie_key": "TOKEN",
        "disable_jwk_security": true,
        "jwk_fingerprints": [
            "S3Jha2VuRCBpcyB0aGUgYmVzdCBnYXRld2F5LCBhbmQgeW91IGtub3cgaXQ=="
        ],
        "cipher_suites": [
            10, 47, 53
        ]
      },
      "issuer-2": {
        "alg": "RS256",
        "jwk-url": "https://url/to/jwks.json",
        "cache": true,
        "audience": [
            "audience1"
        ],
        "roles_key": "department",
        "roles_key_is_nested": false,
        "roles": [
            "sales",
            "development"
        ],
        "issuer": "http://my.api.com",
        "cookie_key": "TOKEN",
        "disable_jwk_security": true,
        "jwk_fingerprints": [
            "S3Jha2VuRCBpcyB0aGUgYmVzdCBnYXRld2F5LCBhbmQgeW91IGtub3cgaXQ=="
        ],
        "cipher_suites": [
            10, 47, 53
        ]
      }
    }
}

During flexible configuration setup, the backend's extra_config is not loaded.

hello. I am setting up a flexible configuration for krakend.
It works fine in most cases, but there are some parts that don't work.

krakend.json

`{
   "version": {{ .service.version }},
   "port": {{ .service.port }},
   "output_encoding": {{ marshal .service.output_encoding }},
   "name": {{ marshal .service.name }},
   "disable_tls_verify": {{ .service.disable_tls_verify }},
   "extra_config":{{ marshal .service.extra_config }},
   "endpoints": [
	   {{ range $idb, $endpoint := .endpoint.private_jwt_ecomon }}
            {{if $idb}} }, {{end}}
            {
            "endpoint": "{{ $endpoint.endpoint }}",
	    "method": "{{ $endpoint.method }}",
            "backend": [
                {
                    "url_pattern": "{{ $endpoint.backend }}",
                    "method": "{{ $endpoint.method }}",
		    "host": "{{  $endpoint.host }}",
                    "extra_config": {
			{{ include "krakend_jose_validator.tmpl" }}
                    },
                    "is_collection": {{ $endpoint.is_collection }}
                }
            ]
           {{ end }}
         },
	 {{ range $idc, $endpoint := .endpoint.jwt_request }}
            {{if $idc}} }, {{end}}
            {
            "endpoint": "{{ $endpoint.endpoint }}",
	    "method": "{{ $endpoint.method }}",
            "backend": [
                {
                    "url_pattern": "{{ $endpoint.backend }}",
                    "method": "{{ $endpoint.method }}",
		    "host": "{{  $endpoint.host }}"
                }
            ]
           {{ end }}
         }
        ]
}
`

partials/krakend_jose_validator.tmpl

`"github.com/devopsfaith/krakend-jose/validator": {
              "alg": "RS256",
              "jwk-url": "***",
              "issuer": "***",
              "roles_key": "***",
              "roles":["***"],
              "is_collection": true,
              "disable_jwk_security": true
              }`

In the private_jwt_ecomon configuration in krakend.json, the extra_config internal file in the backend is not applied.
I also checked with krakend check, but there were no syntax errors.

FC_ENABLE=1 \
FC_SETTINGS="./settings" \
FC_PARTIALS="./partials" \
FC_OUT="/tmp/test.json" \
krakend check -d -c krakend.json

Endpoint: /v1/monitoring/metrics, Method: GET, CacheTTL: 0s, Concurrent: 1, QueryString: []
	Extra (0):
	Backends (1):
		URL: /monitoring/metrics, Method: GET
			Timeout: 2s, Target: , Mapping: map[], BL: [], WL: [], Group: 
			Hosts: [https://192.168.31.10:31443]
			Extra (1):
			  github.com/devopsfaith/krakend-jose/validator: map[alg:RS256 disable_jwk_security:true is_collection:true issuer:*** jwk-url:*** roles:[***] roles_key:***]

I would appreciate it if you could check it out and help me.

Expired token throw token expired error

Currently if passing a expired token it throws 401: Unauthorized. This is hard to debug sometimes, For expired token error message might be useful along the unauthorized part.

401 - Token expired, Unauthorized

JWT Validation. roles_key different from "roles" not working?

Describe the bug
Roles validation responds with 403 if the roles-key if different from "roles".
If I use the role-key "roles" in my endpoint and in my token, the validation works properly, but if I use for example the role-key "apiRoles" in the endpoint and in the token, the validation returns 403.

If I remove the roles validation config, the token validation goes well so it's not a problem related with jwk keys or token headers.

To Reproduce
Steps to reproduce the behavior:

  1. Configuration used
    Endpoint:
{
      "endpoint": "/api/v2/events",
      "method": "GET",
      "output_encoding": "no-op",
      "extra_config": {
        "github.com/devopsfaith/krakend-jose/validator": {
          "alg": "RS256",
          "jwk-url": "http://myapi.com/well-known/jwks.json",
          "disable_jwk_security":true,
          "roles-key":"apiRoles",
          "roles":["admin","readOnly"]
        }
      },
      "backend": [
        {
          "url_pattern": "/api/v2/events",
          "encoding": "no-op",
          "method": "POST",
          "host": ["localhost:8070"]
        }
      ]
    }

Content of the generated token payload:

{
  "apiRoles": [
    "readOnly",
    "admin"
  ],
  "iat": 1614852485,
  "exp": 1615212485
}

Expected behavior
I expect the jose validator to extract the roles list from the "apiRoles" claim in the token payload. And use them to match the roles defined in the endpoint.

Logs

[GIN] 2021/03/04 - 11:13:04 | 403 |    5.263572ms |             ::1 | GET      "/api/v2/events"

Additional context
The token is sent in the Authorization: Bearer header.

Add the ability to use the Well-Known URI to determine the JWK URI

Currently, the JOSE validator only allows to specify a fixed URI from which to retrieve the JWKs needed for token validation. This poses a serious limitation for multi-tenant applications, as usually each tenant will have it's own realm, and thus its own JWKs URI.

It would be great if the JOSE validator could use the JWT issuer claim (iss) and the OIDC Well-Known URI to determine the correct jwk-url to use (found as jwks_uri property in the provider metadata).

This implementation would of course need two calls to retrieve a non-cached key, but it would make the validator way more flexible, and easier to use. Indeed, jwk-url and jwk_local_path would become both optional, and used only if present. This would also ensure retro-compatibility with existing configurations.

As implementation note, looking at the code, l see that the plugin uses a library from Auth0, which maybe is not flexible enough, as it seems that the caching is like "embedded" in the client, which in turn is configured at instantiation time with a fixed URI. This may pose some challenges in implementing this feature request. But I'm no Go developer, so I may be wrong.

Use of a deprecrated API

github.com/auth0-community/go-auth0 used in jwk_client.go is marked deprecated

Extract of README.md of the library

The Auth0 Community is in the process of deprecating this library, and the repository will no longer be available on Github after the end-of-life date of September 30, 2021. Please make plans to find a suitable replacement or remove this library from any active projects before the end-of-life date. The official Auth0 Go SDK is recommended: https://github.com/go-auth0/auth0. Please reach out in the supporting Auth0 Community topic if you have any questions or concerns.

Some questions about the cache

Hi,
it's me again.
While working with KrakenD a few questions and requests arose regarding the cache.

  1. Can you set the cache size? The documentary speaks of 100 entries. That is a little too little in our case.
  2. Does the cache work across endpoints or is a separate cache built for each endpoint?

Prefer strong TLS cipher suites

The JWK client should just support forward secrecy cipher suites and TLS 1.2 or 1.3

Suggested cipher suites to support:

        TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256   uint16 = 0xc02f
        TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
        TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384   uint16 = 0xc030
        TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c
        TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305    uint16 = 0xcca8
        TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305  uint16 = 0xcca9

jwt not validating - Userfront

Hi, I'm using Userfront and attempting to verify a jwt signed and issued by Userfront (they use RS256).

I'm having issue with verifying this token on krakend via the configuration:

"auth/validator": {
    "alg": "RS256",
    "jwk_url": "https://api.userfront.com/v0/tenants/<REDACTED>/jwks",
    "operation_debug": true
  }

Reaching a protected endpoint returns a 401 and on the gateway, it logs:

[ENDPOINT: /auth-test][JWTValidator] Unable to validate the token: illegal base64 data at input byte 20

The JWKs from the jwk_url

{
  "keys": [
    {
      "kid": "4fcc3e4e-8071-4dd5-9a1d-4b3195eb6441",
      "kty": "RSA",
      "use": "sig",
      "alg": "RS256",
      "n": "AOl0DTiZxIcZJ416PBaN+YeCJJZJUtSPWec3GDrm+/VzwAWimT7/My04CZZjWHmHo0cC6C64mLa/xG8rReprylatVfGvWUIuLiek9WVVdxMqg4TtTBiNICB5GzHNpnJ0eCIfi7zpD0Q3Y95C2/odkSJZsKzbcYLeXoqtfSMtw3q9Cl3P6aEqxHLpb5IoRE/rF1cHG60jTuOCOUzxjV4Uo7CMweKz1/Pp3KzF06nHBReSnbaI3QRTP0mW+qj/I6K2jq6umcOBQA65Tv6wQB9KG8sx+miQjIrCMrltecmQ9ruXiF/ArHpuCKDHaNTt5iXhdBc0P2EnZPVREodhYwh1aYVAi2yr+USzsWwhzYaoBXJdInpptfcpdUP4qAuZqLKSLgAY6mIUc1Lps/rgmR1ADWeklj6E887Mt9T+uhjm1abbzEVB9Yqyc+xJUV8gEIwumAAW6WRFqhc6qM8WMGLMPI2wvGXnXYHRquGMmv7HjfBHe4YxQRGfjWyDq3ade8w4zMZ/5okdehZjMaeFHp6VP7hoXh+WAX9t2IxFMarbEC53pMOc4+Co8x0y7Nu/AWwlos/xhEtiUENeLpnDDmU78zhmpYLPGesD56W57lUNSFKtymoS6i6eTQuopfu/UPHc0nMXf9ConBSJbWvKWc5AR4Dx161INTWvx8BZw+cWV3ob",
      "e": "AQAB"
    }
  ]
}

I have a node script that stands up a server with some libs to see that the JWKs and the jwt works:

const Express = require('express');
const jwt = require('express-jwt');
const jwksRsa = require('jwks-rsa');
const logger = require('debug')('express');

const app = new Express();
app.use(
  jwt({
    // Dynamically provide a signing key based on the kid in the header and the signing keys provided by the JWKS endpoint.
    secret: jwksRsa.expressJwtSecret({
      cache: true,
      rateLimit: true,
      jwksRequestsPerMinute: 5,
      jwksUri: `https://api.userfront.com/v0/tenants/<REDACTED>/jwks`,
    }),
    algorithms: ['RS256'],
  }),
);

app.get('/me', (req, res) => {
  res.json(req.user);
});

app.use((err, req, res, next) => {
  logger(err.name, err.message);
  res.json({
    name: err.name,
    message: err.message,
  });
});

// Start the server.
const port = process.env.PORT || 4001;
app.listen(port, function (error) {
  if (error) {
    logger(error);
  } else {
    logger('Listening on http://localhost:' + port);
  }
});

package.json

{
  "name": "scripts",
  "version": "1.0.0",
  "description": "",
  "main": "demo.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "debug": "^2.6.9",
    "express": "^4.17.0",
    "express-jwt": "^6.0.0",
    "jwks-rsa": "^2.1.4"
  }
}

This works and verifies my jwt access token fine.
Furthermore, my jwt does validate on jwt.io debugger with the public key I retrieved from Userfront.

Add option to configure key caching duration

Operating experts requested the ability to configure the key caching time. At first I wanted to suggest changing the type of the cache config parameter from bool to time.Duration, but I think it's better to make a separate parameter for backward compatibility.

Cannot use JWT key for url_pattern in backend

Hello,

I was trying to use a JWT value for the url_pattern in a certain endpoint's backend, and for some keys it works (for other keys does not). I have the following token:

{
  "https://partners.foo.com/roles": [
    "krakend",
    "PORTAL_KAM"
  ],
  "https://partners.foo.com/email": "[email protected]",
  "nickname": "carlos.castro",
  "name": "[email protected]",
  "picture": "https://s.gravatar.com/avatar/077bc3b0517eb18354e0f3ebfb6a0220?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fca.png",
  "updated_at": "2021-02-01T14:07:22.375Z",
  "email": "[email protected]",
  "email_verified": true,
  "iss": "https://partners-foo.auth0.com/",
  "sub": "auth0|5dcc9086defff70f095a1610",
  "aud": "A1YdFI6mIhG0NjozZsjISe1BDx7FdfJR",
  "iat": 1612202845,
  "exp": 1612238845,
  "at_hash": "o9ACF3tTbfLFepKuZPWqtg",
  "nonce": "6_mZthv1SNyRYGZBkah5mRL1ZpF4z07y"
}

When I configure the url_pattern as:

"url_pattern": "/rests-partners-accounts/partners/{JWT.email}/countries",

I see that the requests are correctly routed to /rests-partners-accounts/partners/carlos.castro/countries. However, when I try to configure the url_pattern like this:

"url_pattern": "/rests-partners-accounts/partners/{JWT.https://partners.foo.com/email}/countries",

I see that the request tries to go to /rests-partners-accounts/partners/%7BJWT.https://partners.foo.com/email%7D/countries , as if krakend could not locate the key https://partners.foo.com/email.

Any help would be much appreciated, kind regards.

JWK client with certificate pinning

In order to avoid MITM attacks, the http client loading the keys should support certificate pinning and yield a warning if the feature is not defined.

For example, if using Auth0 jwks endpoint, the client should be pinned to the AWS certificate.

Allow to pass custom headers & choose cache time

Hello,

In my scenario one realm corresponds to one tenant.
Since the jwk-url is static I can't have a dynamic URL for each tenant:
(eg: something like "http://localhost/auth/realms/**${X-Tenant}**/protocol/openid-connect/certs").

One workaround that I tried was to allow passing the original Headers, where I could use the Tenant name to do a custom service where I could know what is the tenant where to check the keys.
But the jwk-url does not pass the original Headers...

I already mentioned this in the slack channel (https://gophers.slack.com/archives/CANCJD0V8/p1604436717237800) and the solution was to build a new plugin...

So, would it be possible to allow, by configuration, to pass the original headers to the jwk url? And also mention if we do want to cache the result?

Thanks,
Filipe

Krakend 1.1.1 not accepting roles

Hello, I've tried to make roles to work using jose-validator but for some reason I'm not able to match any role. The endpoint config is:
"endpoint": "/rests-partners-gateway/rests-partners-accounts/info/",
"method": "GET",
"output_encoding": "json",
"timeout": "900ms",
"headers_to_pass": [ "*" ],
"querystring_params": [ "*" ],
"cache_ttl": "0s",
"extra_config": {
"github.com/devopsfaith/krakend-jose/validator": {
"jwk-url" : "https://partners-foo.auth0.com/.well-known/jwks.json",
"roles_key": "https://partners.foo.com/roles",
"roles": ["krakend"],
"disable_jwk_security": true,
"alg" : "RS256"
}
},

And my token has the following payload:
{
"https://partners.rappi.com/roles": [
"krakend"
],
"nickname": "carlos.castro",
"name": "[email protected]",
"picture": "https://s.gravatar.com/avatar/077bc3b0517eb18354e0f3ebfb6a0220?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fca.png",
"updated_at": "2020-11-26T17:56:18.066Z",
(...)
}
If I remove the roles_key and roles config, all requests with a valid token go through and those that don't receive a 401. But when I add the roles_key and roles directives, I receive a 403 (that according to this PR means the token does not contain the required role. I've checked the playground config and it looks identical (the roles_key being a URL, and such) but still can't get it to work (and running krakend with the -d option does not give any extra output sadly). Am I missing something?
Thanks a lot, and kind regards.

Can't enable JWT validation and signing on the same endpoint

It seems as though even though I've enabled both of these extra_config, only one will be picked up by krakenD

"extra_config": {
        "github.com/devopsfaith/krakend-jose/validator": {
          "alg": "HS256",
          "jwk-url": "http://localhost:9001/jwk",
          "cache": true,
          "roles_key": "roles",
          "roles": [
            "admin",
            "user"
          ],
          "propagate-claims": [
            ["ident", "x-ident"],
            ["user_id", "x-user-id"],
            ["org_id", "x-organization-id"],
            ["jti", "x-jti"]
          ],
          "disable_jwk_security": true
        },
        "github.com/devopsfaith/krakend-jose/signer": {
          "alg": "HS256",
          "kid": "[email protected]",
          "keys-to-sign": [
            "access_token",
            "refresh_token"
          ],
          "jwk-url": "http://localhost:9001/jwk",
          "disable_jwk_security": true
        }
      }
    },

My use case is for that of a refresh token. Using the signed token to access a specific endpoint which then generates another access token and signs it on the way out. I have the access token endpoint working, and I've set up both signing and validation on different endpoints, but during krakend startup there does not seem to be any way to get both a validater and signer on the same endpoint. No error is expressed, but the logs will indicate that either one has been successfully setup (if I supply only one, either works). When both are supplied, only the signer is accepted. Thanks.

Propagate Claims does not overwrite existing headers

Using the "propagate claims" functionality e.g. to extract a field from an incoming JWT Token and forwarding it as a HTTP header, incoming request headers with the same key are not overwritten by the module.

Example:

  • Situation: Propagate claims is set to extract the field "sub" from the JWT and forward it as a custom header "Jwt-Sub".
  • Scenario: An incoming request already contains a header "Jwt-Sub" with a value of "abc"
  • Result: The module passes the original value ("abc") to the backend instead of replacing the incoming value as expected

In effect every client can force a header value into the system

Secret key for encode

How this extra plugin krakend work with secret key for encode payload of response from another services? I need to know what krakend-jose use secret key for validate token from another service with another programing language. Thanks before.

Put HS256 key in krakend configuration

Hello Krakend team,
I'm trying to configure krakend to validate JWT tokens signed with HS256 key. I don't like the idea to serve the key using an endpoint (especially since it's a symmetric key and I need an extra effort to be 100% sure that nobody else except krakend can access the key). Is there a way to avoid using jwk-url parameter and put the key in krakend configuration? Am I missing something here?
Thanks in advance!

Pass through jwt data to backend

Hello,

I'm fairly new to oauth and jwt validation and hope you don't mind if I ask a question about oauth flow here.

I'm using krakend with jose to validate a jwt token issued by okta system. Everything works fine and the token is validated, but, as my api gateway -> backend communication is secure, I want to propagate some of the jwt data to the backend, maybe using a request header. In particular, my backend needs the email of the user doing the request.

Is this a typical scenario? Can jose addon solve it? If not: do I need another krakend piece? I need something not even covered by krakend scope?

CacheDuration ignored

In jose.go, NewValidator takes in the configuration read of extra and builds the internal configuration SecretProviderConfig but forgets to copy CacheDuration which will be then not be sent o

Extract from jose.go code:

func NewValidator(signatureConfig *SignatureConfig, ef ExtractorFactory) (*auth0.JWTValidator, error) {
	....
	cfg := SecretProviderConfig{
		URI:                 signatureConfig.URI,
		CacheEnabled:        signatureConfig.CacheEnabled,
		Fingerprints:        decodedFs,
		Cs:                  signatureConfig.CipherSuites,
		LocalCA:             signatureConfig.LocalCA,
		AllowInsecure:       signatureConfig.DisableJWKSecurity,
		LocalPath:           signatureConfig.LocalPath,
		SecretURL:           signatureConfig.SecretURL,
		CipherKey:           signatureConfig.CipherKey,
		KeyIdentifyStrategy: signatureConfig.KeyIdentifyStrategy,
	}

	sp, err := SecretProvider(cfg, te)
	if err != nil {
		return nil, err
	}

As a consequence, SecretProvider won't receive the provided CacheDuration available in signatureConfig.

Validating JWT scopes at the API gateway

Normally, when you communicate with an API endpoint, you request an JWT / token with corresponding scopes for it (at your identity provider / secure token service), that you then send along with the request (typically in the Authorization header as a Bearer token).

Now think of an API that manages customers. If you want to access that API to read a customer object, your application would - after authenticating against the identity server (e.g. Auth0, Azure Active Directory etc.) - request an access token on behalf of the current user with the scope "Customer.Read". If the identity server is allowing to request such a scope for that particular application, it is then included in the returned access token (JWT) - in a special claim called "scope" (for Auth0) or "scp" (for AAD). That claim is normally validated by the API/backend that receives the request...and based on the scopes provided, allows the operation to be fulfilled or the access is denied returning a 403 http status code.

It would be great to being able to inspect the "scope" claim directly at the API gateway level and block or allow all requests based on required scopes to be present in the JWT. Configuration could look something like that:

"github.com/devopsfaith/krakend-jose/validator": {
    "alg": "RS256",
    [...]
    [...]
    "scopes": ["Customer.Read"],
    "scopes_key": "scope"
    [...]
    [...]
}

Because the claim can be different depending on the identity solution you are using, you would need to define a scopes_key (claim to use from the token - like roles_key - maybe it also makes sense to allow a "nested claim"). The scopes array would then the define the required scopes to be present in the token. If you add multiple values, e.g. "scopes": ["Customer.Read", "Customer.Create"] all values must be present. Or you could also introduce a "matcher" property like "scopes_matcher": "any" (at least one must match) or "scopes_matcher": "all" (all scopes must be present).

Example:

Sample JWT

{
  "aud": "https://myapi.com",
  "iss": "https://myissuer.com/",
  [...],
  [...],
  "family_name": "Doe",
  "given_name": "John",
  "scope": "Customer.Read Customer.Create",
  "sub": "myuserid",
  [...],
  [...],
}

Configuration Endpoint1

"github.com/devopsfaith/krakend-jose/validator": {
    "alg": "RS256",
    [...]
    [...]
    "scopes": ["Customer.Read", "Customer.Create"],
    "scopes_key": "scope",
    "scopes_matcher": "all"
    [...]
    [...]
}

Result: Request is allowed.

Configuration Endpoint2

"github.com/devopsfaith/krakend-jose/validator": {
    "alg": "RS256",
    [...]
    [...]
    "scopes": ["Customer.Read", "Customer.Update"],
    "scopes_key": "scope",
    "scopes_matcher": "all"
    [...]
    [...]
}

Result: Request is NOT allowed, because scope "Customer.Update" is not included (and matcher is set to "all").

Configuration Endpoint3

"github.com/devopsfaith/krakend-jose/validator": {
    "alg": "RS256",
    [...]
    [...]
    "scopes": ["Customer.Read", "Customer.Update"],
    "scopes_key": "scope",
    "scopes_matcher": "any"
    [...]
    [...]
}

Result: Request is allowed, because scope matcher is set to "any" and therefore, only one of the scopes needs to be included.

Being able to block requests directly at the API gateway based on scopes would be a great benefit, because you could "lock out traffic at the frontdoor" of your application and don't need to deal with communication that isn't even supposed to work at the backend.

Would love to contribute that one...but let's discuss what you think of such a feature.

Cheers,
Christian

CC: @alombarte as discussed.

JWK validation settings cache doesnt work

Describe the bug
I have jwk set, signer, and validator config like this code below. I assume when adding "cache": false in signer & validator config, the jwk URL I provided will always get hit. But it doesn't seem to do so.
The way I test this is that I tried to change the content of the JWK after krakend started, hoping to see the JWT validation failed. It seems like Krakend still hit the old URL all the time despite the cache setting.
Please help / advise. Below is my config

Your configuration file
JWK symmetric.json

{
  {
	"keys": [
		{
			"kty": "oct",
			"alg": "A128KW",
			"k": "GawgguFyGrWKav7AX4VKUg",
			"kid": "sim1"
		},
		{
			"kty": "oct",
			"k": "AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow",
			"kid": "sim2",
			"alg": "HS256"
		}
	]
}
}

Signer

{
    "endpoint": "/login",
    "method": "POST",
    "headers_to_pass": [
    "*"
    ],
    "backend": [
    {
      "url_pattern": "/v1/auth/login",
      "extra_config": {
        "github.com/devopsfaith/krakend/transport/http/client/executor": {
          "name": "grpc-gateway-auth",
          "endpoints": [ "localhost:10001" ]
        }
      }
    }
    ],
    "extra_config": {
        "github.com/devopsfaith/krakend-jose/signer": {
            "alg": "HS256",
            "kid": "sim2",
            "keys-to-sign": ["access_token","refresh_token"],
            "jwk-url": "http://localhost/symmetric.json",
            "disable_jwk_security": true,
            "cache": false,
            "cache_duration": 0
        }
    }
}

Validator

{
    "endpoint": "/login",
    "method": "POST",
    "headers_to_pass": [
    "*"
    ],
    "backend": [
    {
      "url_pattern": "/v1/auth/login",
      "extra_config": {
        "github.com/devopsfaith/krakend/transport/http/client/executor": {
          "name": "grpc-gateway-auth",
          "endpoints": [ "localhost:10001" ]
        }
      }
    }
    ],
    "extra_config": {
        "github.com/devopsfaith/krakend-jose/signer": {
            "alg": "HS256",
            "kid": "sim2",
            "keys-to-sign": ["access_token","refresh_token"],
            "jwk-url": "http://localhost/symmetric.json",
            "disable_jwk_security": true,
            "cache": false,
            "cache_duration": 0
        }
    }
}

Commands used
How did you start the software?

#Example:
docker run --rm -it -v $PWD:/etc/krakend \
        -e FC_ENABLE=1 \
        -e FC_SETTINGS="/etc/krakend/config/settings" \
        -e FC_PARTIALS="/etc/krakend/config/partials" \
        -e FC_OUT=out.json \
        devopsfaith/krakend \
        run -c /etc/krakend/config/krakend.json -d

Expected behavior
The way I test this is that I tried to change the content of the JWK after krakend started, hoping to see the JWT validation failed. It seems like Krakend still hit the old URL all the time despite the cache setting

Logs
If applicable, any logs you saw in the console and debugging information

Additional context
Add any other context about the problem here.

Improve initial logs

the current log is kind of confusing:

[KRAKEND] 2019/01/27 - 19:33:05.623 ▶ ERROR JOSE: no signer config /v3/channel/:channel/media
[KRAKEND] 2019/01/27 - 19:33:05.624 ▶ ERROR JOSE: no signer config /nick/:user
[KRAKEND] 2019/01/27 - 19:33:05.624 ▶ ERROR JOSE: no signer config /form
[KRAKEND] 2019/01/27 - 19:33:05.624 ▶ ERROR JOSE: no signer config /get

Instead of jwk-url is there is a way to directly load public key input ?

JWT's can be validated offline without the need for internet. Instead of retrieving public key from the jwk_url to verify the signature is there is a way to directly load the public key ? may as a input via text box.

Sample input: Basically Offline validation

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhAj9OCZd0XjzOIad2VbUPSMoVK1X8hdD2Ad+jUXCzhZJf0RaN6B+79AW5jSgceAgyAtLXiBayLlaqSjZM6oyti9gc2M2BXzoDKLye+Tgpftd72Zreb4HpwKGpVrJ3H3Ip5DNLSD4a1ovAJ6Sahjb8z34T8c1OCnf5j70Y7i9t3y/j076XIUU4vWpAhI9LRAOkSLqDUE5L/ZdPmwTgK91Dy1fxUQ4d02Ly4MTwV2+4OaEHhIfDSvakLBeg4jLGOSxLY0y38DocYzMXe0exJXkLxqHKMznpgGrbps0TPfSK0c3q2PxQLczCD3n63HxbN8U9FPyGeMrz59PPpkwIDAQAB
-----END PUBLIC KEY-----

Error with devopsfaith/krakend-jose/validator jwk-url

Hello everyone!
I found problem with IdentityServer4 and Krakend, when i wrote in jwk-url {identity address}.well-known/openid-configuration/jwks, Krakend wrote to the log - "ERROR answer isn't json", but IS4 response Content-type application/jwk-set+json with current body.
Could you add suppory Content-Type application/jwk-set+json for jwk-url parameter?

krakend version

Is it possible to update dependency for KrakenD 0.7.0 or create a release for that KrakenD version?

Allow 'any' matching strategy for audience claim

The audience matching configuration takes a list of audience values and a token is considered valid when all values are present in the token.
In scenarios where a backend is supposed to serve multiple clients, each having a single but different audience value, a behavior where any match is sufficient is desired. This cannot be achieved with the current configuration option.
As a workaround, one can use the roles matching by setting "roles_key": "aud" but this is not very intuitive (and then no other claims can be checked using this mechanism).
Instead, I propose to add a configuration option similar to scopes_matcher to allow changing of the audience matching strategy.

Also it'd be useful to add to the documentation a note that indicates that the default behavior is to require a match of all audience values.

The deprecation of github.com/auth0-community/go-auth0 breaks build

As per https://community.auth0.com/t/community-repo-deprecation-auth0-go/64665 , it was said that this line https://github.com/devopsfaith/krakend-jose/blob/90b8fe32a9fd493ded8e74d1fbcaddd0e8674ffb/go.mod#L6 has been deprecated since long ago by the new https://github.com/go-auth0/auth0 , last week IIRC the deprecated repo was still available so no error happened, but as of today the deprecated repository (github.com/auth0-community/go-auth0) seems to have return 404 (looks like the repo has been deleted in the end).

Do you accept a PR for this matter?

FileKeyCache needs nil check in Get() to avoid crash in go-auth0 JWK client

The FileKeyCache Get() function (line 120 of jwk.go in master) can return (nil, nil) if the provided key ID is not found. It should return a non-nil error (probably ErrNoKeyFound) in that case, otherwise GetKey() in github.com/auth0-community/go-auth0/jwk_client.go crashes because it expects either the key or the error to be non-nil.

2021/03/01 23:49:12 [Recovery] 2021/03/01 - 23:49:12 panic recovered:
runtime error: invalid memory address or nil pointer dereference
/usr/local/go/src/runtime/panic.go:212 (0xec8c92)
/usr/local/go/src/runtime/signal_unix.go:742 (0xec8b12)
/go/pkg/mod/github.com/auth0-community/[email protected]/jwk_client.go:80 (0x1f04341)
/go/pkg/mod/github.com/devopsfaith/[email protected]/jwk_client.go:90 (0x20926f9)
/go/pkg/mod/github.com/auth0-community/[email protected]/auth0.go:102 (0x1f03d44)
/go/pkg/mod/github.com/devopsfaith/[email protected]/gin/jose.go:119 (0x2240db7)
/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:161 (0x1a201da)
/go/pkg/mod/github.com/gin-gonic/[email protected]/recovery.go:83 (0x1a34244)
/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:161 (0x1a201da)
/go/pkg/mod/github.com/gin-gonic/[email protected]/logger.go:241 (0x1a33344)
/go/pkg/mod/github.com/gin-gonic/[email protected]/context.go:161 (0x1a201da)
/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:409 (0x1a2a519)
/go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:367 (0x1a29c0c)
/Users/jesperp/Downloads/krakend-sec/auth.go:49 (0x7f4728b697e4)
/usr/local/go/src/net/http/server.go:2042 (0x11f85a3)
/usr/local/go/src/net/http/server.go:2843 (0x11fbca2)
/usr/local/go/src/net/http/server.go:1925 (0x11f73ac)
/usr/local/go/src/runtime/asm_amd64.s:1374 (0xeea3c0)

Cannot pass claims to the backend URL

Here is my payload
{ "sub": "1234567890", "name": "Mr. KrakenD" }

Having a backend defined like

{ "url_pattern": "/foo/{JWT.sub}", "method": "POST" ... }

Trying to call on URL got

[GIN] 2021/01/14 - 11:55:59 | 500 | 1.913632139s | ::1 | POST "/krakend/foo" Error #01: Invalid status code

Expected behavior

POST /foo/1234567890

Can I get the http statue code 403, when the roles_key isn't in my "roles" list ?

This is my config:

    {
      "endpoint": "/gcrpc/user.User/View",
      "headers_to_pass": ["*"],
      "output_encoding": "no-op",
      "method": "POST",
      "backend": [{
        "url_pattern": "/gcrpc/user.User/View",
        "sd": "etcd",
        "disable_host_sanitize":true,
        "encoding": "no-op",
        "host": [
          "micro-rpc-user"
        ]
      }],
      "extra_config": {
        {{ include "jose_validator_admin.tmpl" }} 
      }
    },

jose_validator_admin.tmpl

"github.com/devopsfaith/krakend-jose/validator": {
    "alg": "HS256",
    "kid": "sim2",
    "jwk-url": "http://127.0.0.1:33000/jwk/symmetric.json",
    "disable_jwk_security": true,
    "roles_key": "rs",
    "roles": [
        "r_admin",
        "development"
    ]
}

The result I get :

[GIN] 2019/02/25 - 16:46:27 | 401 |     396.762µs |   113.88.98.137 | POST     /gcrpc/user.User/View

And I saw the code below:

https://github.com/devopsfaith/krakend-jose/blob/afde91ecf17c4c1d0d759099743f3151b5c3d66f/gin/jose.go#L113

Why not return the http status code 403 ?

Krakend 1.1.1 cannot parse roles in large token

Hello,

Sometimes (depending on the token), krakend seems unable to properly parse a token and the roles end up not working. I am using a short-payload token that has the following content:

{
  "iss": "https://nico-test.us.auth0.com/",
  "sub": "oZ4Qwz7G3ep60tcNblYttUWFl4NqD3tT@clients",
  "aud": "https://el.pulpo.com",
  "iat": 1606424904,
  "exp": 1606511304,
  "azp": "oZ4Qwz7G3ep60tcNblYttUWFl4NqD3tT",
  "gty": "client-credentials",
  "permissions": [
    "foo",
    "bar"
  ]
}

With the following endpoint config:

      "endpoint": "/rests-partners-gateway/rests-partners-accounts/info/",
      "method": "GET",
      "output_encoding": "no-op",
      "extra_config": {
              "github.com/devopsfaith/krakend-jose/validator": {
                  "roles_key": "permissions",
                  "roles": ["bar"],
                  "jwk-url" : "https://nico-test.us.auth0.com/.well-known/jwks.json",
                  "disable_jwk_security": true,
                  "alg" : "RS256"
              }
      },

In this case, kraken is able to check the "permissions" key and verify if the role "bar" is in there. When using a different role in the token, I get a 403 (as expected).

Thing is, with the following token:

{
  "https://partners.foo.com/roles": [
    "krakend"
  ],
  "nickname": "carlos.castro",
  "name": "[email protected]",
  "picture": "https://s.gravatar.com/avatar/077bc3b0517eb18354e0f3ebfb6a0220?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fca.png",
  "updated_at": "2020-11-26T17:56:18.066Z",
  "email": "[email protected]",
  "email_verified": true,
  "iss": "https://partners-foo.auth0.com/",
  "sub": "auth0|5dcc9086defff70f095a1610",
  "aud": "A1YdFI6mIhG0NjozZsjISe1BDx7FdfJR",
  "iat": 1606413378,
  "exp": 1606449378,
  "at_hash": "c5WgSZhJAAqS_uH9pgFMVg",
  "nonce": "PZ~o1BijmVPeFYK-a0xjBeICMfJfm03k"
}

and the following endpoint config:

      "endpoint": "/rests-partners-gateway/rests-partners-accounts/info2/",
      "method": "GET",
      "output_encoding": "no-op",
      "extra_config": {
              "github.com/devopsfaith/krakend-jose/validator": {
                  "roles_key": "https://partners.foo.com/roles",
                  "roles": ["krakend"],
                  "jwk-url" : "https://partners-foo.auth0.com/.well-known/jwks.json",
                  "disable_jwk_security": true,
                  "alg" : "RS256"
              }
      },

I get a 403 every time, as if the token didn't have the role "krakend" in the key "https://partners.foo.com/roles". Besides attempting to change the key for something else/simpler, is there anything in the JWT that would cause this strange behavior?

Thanks a lot, kind regards.

ACL roles and regex checks enhancement

Hello,

I'm using this Krakend plugin for JWT validation, in particular I'm focusing on the ACL validation functionality: roles_key and roles.

It works well, but for a project I need to check if a given role contains words. With this plugin is not possible to do this but only check if the the given role is in the roles list.

So my suggestion is:

  1. Adding a new setting at L27 like roles_regex: true/false
  2. In the method CanAccess, if the previous property roles_regex exists and it is true do something like this instead of the standard check:
func CanAccess(roleKey string, claims map[string]interface{}, required []string, roleRegex bool) bool {
	
	...
	
	for _, role := range required {
		for _, r := range roles {
		
			if roleRegex {
				reg, _ := regexp.Compile(role)
				if reg.MatchString(r) {
					return true
				}
			}
			else {
				if r.(string) == role {
					return true
				}
			}
		}
	}
	
	return false
}

So in the JWT validation plugin settings I could have:

{
    "endpoint": "/protected/resource",
    "extra_config": {
        "github.com/devopsfaith/krakend-jose/validator": {
            "alg": "RS256",
            "audience": ["http://api.example.com"],
            "roles_regex": true,
			"roles_key": "roles",
            "roles": ["(\b)?+(.guest.)+(\b)?", "(\b)?+(.admin.)+(\b)?"],
            "jwk-url": "https://albert-test.auth0.com/.well-known/jwks.json"
        }
    },
    "backend": [
        {
        "url_pattern": "/"
        }
    ]
}

In this way I'm able to grant access at roles:

001.admin.0002
002.admin.0002 

What do you think about this possbile enhancement?

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.