Git Product home page Git Product logo

lua-resty-openidc's People

Contributors

arcivanov avatar asbjornu avatar barrelmaker97 avatar bodewig avatar bungle avatar cdbattags avatar chipitsine avatar davidbirdsong avatar derekamz avatar dewiedn avatar dholth avatar dudssource avatar gdestuynder avatar gene1wood avatar gonzalad avatar grrolland avatar hanikesn avatar iperdomo avatar joshbarr avatar kg0r0 avatar membphis avatar oleeander avatar pamiel avatar petercoppensdatylon avatar therealcmj avatar thomasleplus avatar thorstenfleischmann avatar usysrc avatar zandbelt avatar zhuizhuhaomeng 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  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

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

lua-resty-openidc's Issues

outgoing proxy support

Hi, we've got lua-resty-openidc working, and are now trying to get it to work in an environment that requires all traffic to go through an outbound proxy. We are getting a connection refused error when trying to access the discovery URL. We have installed the lua-resty-socket module but we're amateurs at lua. Could you point us in the right direction to get openidc to use a proxy?

session state doesn't match state

I keep getting this error when trying to configure openidc

openidc.lua:294: authenticate(): state from argument: adf7c9545d2d880ec073c96b63da7a60 does not match state restored from session: nil

Note I have the latest version of lua-resty-session installed as I have read that the session_check_ssi has caused problems in the past... any ideas?

"invalid token: No trusted certs loaded", client: 10.12.147.129

Hello,
I am using following code to verify the token from keycloak,
local json, err, access_token = require("resty.openidc").bearer_jwt_verify(utils.get_options(config, ngx))
but an error was returned "invalid token: No trusted certs loaded", can someone tell what certs needs to be load and how to load it? thanks

Mismatched state error

I'm getting an error related to sessions:

2017/03/23 01:01:26 [error] 11317#0: *1 [lua] openidc.lua:294: authenticate(): state from argument: 4ba273aded3294e5684674a39fe778cce23f84ead624db4b does not match state restored from session: a60dd9fb58feda4d72eee2af52a79789, client: 10.0.1.26, server: <snip>.com, request: "GET /auth/google/callback?state=4ba273aded3294e5684674a39fe778cce23f84ead624db4b&code=4/PvFKMkF62CiOupt3aRQC3PHanzlvV0NDh2dJnMwqYeo HTTP/1.1", host: "<snip>.com"

My relevant Nginx config is:

location / {
    set $session_secret <snip>;
    access_by_lua '

      local opts = {
         -- the full redirect URI must be protected by this script and becomes:
         -- ngx.var.scheme.."://"..ngx.var.http_host..opts.redirect_uri_path
         -- unless the scheme is overridden using opts.redirect_uri_scheme or an X-Forwarded-Proto header in the incoming request
         redirect_uri_path = "/auth/google/callback",
         discovery = "https://accounts.google.com/.well-known/openid-configuration",
         client_id = "snip.apps.googleusercontent.com",
         client_secret = "snip",
         authorization_params = { hd="snip.com" },
         --scope = "openid email profile",
         --iat_slack = 600,
         --redirect_uri_scheme = "https",
         --logout_path = "/logout",
         --token_endpoint_auth_method = ["client_secret_basic"|"client_secret_post"],
         ssl_verify = "no"
      }

      -- call authenticate for OpenID Connect user authentication
      local res, err = require("resty.openidc").authenticate(opts)

      if err then
        ngx.status = 500
        ngx.say(err)
        ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
      end

      -- at this point res is a Lua table with 3 keys:
      --   id_token    : a Lua table with the claims from the id_token (required)
      --   access_token: the access token (optional)
      --   user        : a Lua table with the claims returned from the user info endpoint (optional)

      --if res.id_token.hd ~= "pingidentity.com" then
      --  ngx.exit(ngx.HTTP_FORBIDDEN)
      --end

      if res.user.email ~= "@snip.com" then
        -- ngx.exit(ngx.HTTP_FORBIDDEN)
      end

      -- set headers with user info (overwriting any existing!)
      ngx.req.set_header("X-USER", res.id_token.sub)
    ';

    try_files $uri @app;
    break;
  }

I did try set $session_secret snip; in the server{} block, and also memcached for sessions but stil get this error. The environment is on AWS behind an ELB that does SSL termination and forwards the decrypted traffic to nginx on port 80. For the time being I've limited the backend to one server which is running Nginx with worker_processes 1;. I also tried turning off the lua code cache, but to no avail.

Any help with this would be welcome.

Add support for passing options to resty.session

I'd like to add support for resty.openidc passing resty.session options into resty.session in order to set session settings.

In my specific case I'm doing two OIDC code flows against different OPs and need to establish distinct OIDC sessions with each OP. Consequently I need to be able to set the resty.session name.

Clarify documentation around refresh_session_interval vs access_token_expires_in

The readme currently says:

    -- Refresh the user's id_token after 900 seconds without requiring re-authentication
    --refresh_session_interval = 900,
    ...
    --access_token_expires_in = 3600
    -- Default lifetime in seconds of the access_token if no expires_in attribute is present in the token 
    endpoint response.
       This plugin will silently renew the access_token once it's expired if refreshToken scope is present.

I interpreted this to mean:

  • If less than 900 seconds have passed, don't validate anything, reuse the existing session.
  • If between 900 and 3600 seconds have passed, silently refresh the id_token/access token server side using the refresh token, but with no client side redirects.
  • If >3600 seconds have passed, then redirect the client to the OP for re-authentication.

Whereas from reading the source the behaviour is actually:

  • If less than 900 seconds have passed, don't validate anything, reuse the existing session.
  • If >900 force refresh of the access token by redirecting the client to the OP with prompt = "none".
    (Presuming the access token returned from the OP doesn't have an expiry of its own which is shorter than 3600 seconds)

If I've interpreted the behaviour correctly, it would seem the refresh_session_interval description in the docs might be more accurately worded as:

Redirect the client to the OP (but with no authentication prompt) after 900 seconds to refresh their id_token and access token.

Also the access_token_expires_in description should probably read:

...
This plugin will silently renew the access_token once it's expired if refreshToken scope is present, so long as refresh_session_interval is not set.

Many thanks!

Lua runtime error when the Host header is not set

I spotted this in the nginx error log (using lua-resty-openidc 1.3.2-1 and openresty 1.11.2.3):

2017/06/03 00:18:17 [error] 17499#17499: *76717 lua entry thread aborted: runtime error: /usr/share/lua/5.1/resty/openidc.lua:139: attempt to concatenate field 'http_host' (a nil value)
stack traceback:
coroutine 0:
        /usr/share/lua/5.1/resty/openidc.lua: in function 'openidc_get_redirect_uri'
        /usr/share/lua/5.1/resty/openidc.lua:173: in function 'openidc_authorize'
        /usr/share/lua/5.1/resty/openidc.lua:642: in function 'authenticate'
        .../local/openresty/nginx/conf/SNIP/openidc_layer.lua:27: in function <.../local/openresty/nginx/conf/SNIP/openidc_layer.lua:1>, client: SNIP, server: , request: "GET /scripts/nph-test-cgi?* HTTP/1.0"

Looks like someone was running a scanner against the site, which wasn't setting the Host header.

Presumably this should be null-checked before use?

Interaction required error from token end point

I am getting this issue suddenly. not sure why I am getting this. We are working with Microsoft azure OAuth. Can someone tell how you fixed this issue? I referred to issue #8 where it was fixed by redirecting the user to original url. Can you paste the sample code that can be used in nginx.conf file to fix this ?

The below error is coming from openidc_call_token_endpoint method. We should redirect the user to Microsoft auth page whenever interaction_required error is seen, once he completes the additional authentication then bring him back.

response indicates failure, status=400, body={"error":"interaction_required","error_description":"AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access '00000002-0000-0000-c000-000000000000'.\r\nTrace ID: 5889afab-8ce9-40da-b5fb-c76b4f420000\r\nCorrelation ID: 215515f1-8f10-4ed6-b4a8-fda77d259dcc\r\nTimestamp: 2017-05-09 23:30:44Z","error_codes":[50076],

We have MFA setup within our org. during the initial authentication microsoft automatically takes to OTP page and completes the authentication but not sure from where this interaction_ required error is hit again. I have 2 machines in different locations, the flow is working fine from one machine where OTP page is shown, but it is not working from other location where OTP page is not shown. Hope my explanation is clear

Where should I put OIDCCryptoPassphrase ?

I am migrating from the mod_auth_openidc Apache plugin to lua-resty-openidc with Nginx. In Apache I had my OAuth2 provider JsonWebToken Signature Algorithm set to RS256. With this setting the lua-resty-openidc module is in a redirect loop with the OAuth2 provider. I changed the algorithm to HS256 and now the first request authenticates fine but subsequent requests trigger authentication redirect (it appears session is not being kept). In the logs I have:

ignoring stale global SSL error (SSL: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt)

and I saw your response to #26 so I tried setting:

set $session_cipher none;

no difference, first request is authenticated, subsequent requests trigger authentication.

Also tried:

set $session_secret 623q4hR325t36VsCD3g567922IC0073T;

and no difference.

I am trying to move away from mod_auth_openidc because websockets are not working when both Apache & Nginx are involved (I need some Nginx-specific features). In Apache I had OIDCCryptoPassphrase and I am not sure where to put this variable in lua-resty-openidc or if it is related to the problem at all...

Is the client_secret for Google+ Signin and the secret for JWT the same thing?

I have a scenario where I want to use the redirect-based approach most of the time, but in one case I need to do CORS from JavaScript. If I create another endpoint using the JWT config, can I pass a jwt from the client and have lua-resty-openidc verify it with the client_secret? My signature algorithm is HS256. The client obtains the jwt token through a different path (which doesn't involve nginx).

Support for JWT via discovery without x5c

In the available documentation Sample Configuration for OAuth 2.0 JWT Token Validation, there is a comment: -- The jwks endpoint must provide a x5c entry

I just hit an issue when trying to validate a token:

2017/02/10 09:44:04 [debug] 7#7: *2 [lua] openidc.lua:411: openidc_jwks(): Response data: {"keys":[{"kid":"YDAkh8zPFq5KdfnqtZZlpVG2fajlLzAcqh7BmV289JE","kty":"RSA","alg":"RS256","use":"sig","n":"qT3Lnddxydyj1-clZwcsFVisAEgglHMQbcJgozhlDC3vHFV2b_-xIqEEQtC56CgdPGe4LVwDBcNOp5a23OheVPzaTAdr2JwNqVg8Oeen0ba2ca-fBySXJyUEP2qmlIW5Ar7kexqRT-LhGCCf3iA3Bjs2o_PIH5Eu5V3AaubnZO1hqni7VVHpF0QdLmfVCBWK6FoxrEqedRuPFHLoX4GF3tUTk-drPoEwe3Tf_J6UICAp1QaRr-hGVyKsIf0gjru8ArzFcLfZuH21ZJJ6QWuFGCFFe90KCWC3LdTzyYB5byq3z915E9MeEH0zraTPCs0_OelzuzjpUVQQsy6BNJwEww","e":"AQAB"}]}
2017/02/10 09:44:04 [debug] 7#7: *2 lua resume returned 2
2017/02/10 09:44:04 [error] 7#7: *2 lua entry thread aborted: runtime error: /usr/local/openresty/luajit/share/lua/5.1/resty/openidc.lua:458: attempt to index local 'x5c' (a nil value)
stack traceback:
coroutine 0:
	/usr/local/openresty/luajit/share/lua/5.1/resty/openidc.lua: in function 'pem_from_jwk'
	/usr/local/openresty/luajit/share/lua/5.1/resty/openidc.lua:694: in function 'bearer_jwt_verify'
	access_by_lua(nginx.conf:73):22: in function <access_by_lua(nginx.conf:73):1>, client: 172.17.0.1, server: , request: "GET /api HTTP/1.1", host: "localhost:8082"

There is TODO entry to check the x5c length at https://github.com/pingidentity/lua-resty-openidc/blob/v1.3.0/lib/resty/openidc.lua#L457

Our provider implementation don't expose this key, and it seems that google certs also don't expose a x5c property in their certs:

I was wondering why x5c is a requirement for validation? I wouldn't like to hardcode the cert in the nginx.conf so I was trying to get the public cert via discovery. (Perhaps i'm missing something)

Question on JWT Token Validation

I am trying to validate my access_token using https://github.com/pingidentity/lua-resty-openidc#sample-configuration-for-oauth-20-jwt-token-validation-1. Somehow I wasn't able to succeed. My goal is to protect my apis using this approach. Here is my configuration. Am I missing something here. I am getting 2 issues here. Can someone tell me where I am going wrong. I was able to verify the signature using jwt.io

  1. With the below configuration, I am getting openidc_discover(): accessing discovery url (https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration) failed: 20: unable to get local issuer certificate, client:

  2. When I added secret (public key string from my secret.crt file) I am getting "reason":"Verification failed","raw_header":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6InowMzl6ZHNGdWl6cEJmQlZLMVRuMjVRSFlPMCIs

location /api {
      access_by_lua '
          local opts = {
            -- The jwks endpoint must provide a x5c entry
   discovery = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration"
          }
          -- call bearer_jwt_verify for OAuth 2.0 JWT validation
          local res, err = require("resty.openidc").bearer_jwt_verify(opts)
..
..
    }
  }
}

I am sending Curl request with authorization token to test if my /api is secured or not like below
curl -i http://myserver.com/api/index.html -H 'Authorization: bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6InowMzl6ZHNGdWl6cEJmQlZLMVRuMjVRSFlPMCIs'

Infinite authentication loop

With 1.2.3 the encrypted id_token is saved in the session data (#29). This pushes the session cookie size above 4 kb with e.g. Azure Active Directory and thus the cookie will not be stored by most browsers.

Possible workarounds are to use a different session store. Using a gzip based session encoder might also be an option.

If session does not match, redirect omits port

I'm using https://localhost:8443/ as a test server. It looks like a redirect on the error path drops the port.

  1. Set lua_code_cache off without setting an explicit session secret. This causes resty.session to choose a new secret for every request, and it will not be able to decode session cookies.
  2. Visit protected URL, get redirected to IdP
  3. Redirect back to callback URL
  4. Redirect to https://localhost/ with no port

OPM Question

Do you plan on adding this nifty module to OPM?
Just wondering because it would be nice to have.
Thanks!

Question about redirect_uri_path

This issue is similar to issue #7

Once the Authentication provider redirects the page back. The browser with redirect_uri in this case (/secured) with all the scope, state and code parameters doesn't show anything. I am trying to redirect the user to Home page in this case its http://xyz.abc.com:8888. When I manually modify the url by removing the string starting from secured, it works.

Sometimes the redirection happens correctly to the Home page http://xyz.abc.com:8888 without /secured querystring.

Here is the url that is coming back after authentication
Initial Url:

http://xyz.abc.com:8888

Return Url:

http://xyz.abc.com:8888/secured?code=AQABAAIAAADRNYRQ3dhRSrm-4K-adpCJ7YXOwPP2_C_d2P7-QxX1uqmYzl1YXCS4i8Re3wSlYhmj7HNv-2s0_Y41P20yHNCfYJq6joqiMJ6C-Q3ot524UnRPBfjwFhpOlcr4gAA&state=107364f895c8f787fb28d&session_state=c8b0a1f4-fcee-4c98-9351-dfda1

Here is the conf file

    # authentication
    location ~ (\.cgi$|(^/(logout|secured)$)) {
        set $auth_email "";
        set $auth_realname "";
        access_by_lua '
          local opts = {
             -- the full redirect URI must be protected by this script and becomes:
             -- ngx.var.scheme.."://"..ngx.var.http_host..opts.redirect_uri_path
             -- unless the scheme is overridden using opts.redirect_uri_scheme or an X-Forwarded-Proto header in the incoming request
             redirect_uri_scheme = "http"
             redirect_uri_path = "/secured",
--          Need to make sure discovery path matches the response data
             discovery = "https://login.microsoftonline.com/../.well-known/openid-configuration",
             client_id = "xxxxx",
             client_secret = "xxxxxxxyyyyyy,
             --ssl_verify = "no"
             --authorization_params = { hd="pingidentity.com" },
             --scope = "openid email profile",
             iat_slack = 600,
             --logout_path = "/logout",
             token_endpoint_auth_method ="client_secret_post",
          }

Thanks in advance!

Upload Docker image to Docker Hub

To be able to upload a Docker image of lua-resty-openidc, an organization and repository need to be set up on Docker Hub. When that's done, we should add a docker push step to the after_deploy section of the .travis.yml file, so a new Docker image is uploaded for every new tag that is built.

Check issued-at timestamp is failing

The lua-resty-openidc plugin is failing for us on simple requests. The problem is likely caused by differences in time synch and/or latency between our Ping server and our app servers running on AWS & Verizon clouds.

We're seeing the following message in our logs:

2015/09/29 19:30:56 [error] 18972#0: *4 [lua] openidc.lua:90: openidc_validate_id_token(): token is not valid yet: id_token.iat=1443554983, os.time()=1443555056, client: <client_ip>, server: , request: "GET /redirect_uri?state=&code= HTTP/1.1", host: "<server_ip:port>"

Increasing the value in the script to 1000 fixes the problem for us. Is there a reason for the hard-coded 10ms value in the script? Is it reasonable to increase that value or to parameterize it so that implementations can override in config files?

Question about reverse proxy

I use lua-resty-openidc for protecting some services in a docker environment. I’ve defined Nginx as a reverse proxy for protected Apps, everything works fine (in a really nice way).
Recently I would like to try the reverse proxy traefik.

Now I tested the reverse proxy traefik.
So, I put traefik in front of Nginx and traefik manage the ssl stuff. By this way Nginx is just here for protecting Apps and manage the OpenId Connect authentication.
But with this configuration it did not work.

server { 
    listen       80;
    server_name  "kibana.acme.org";
    access_log off;

    location / {
        access_by_lua '
                local cjson = require "cjson"

                function inTable(tbl, item)
                    for key, value in pairs(tbl) do
                        if value == item then return key end
                    end
                    return false
                end

               local opts = {
                    redirect_uri_path = "/redirect_uri",
                    discovery = os.getenv("DISCOVERY"),
                    client_id = os.getenv("CLIENT_ID"),
                    client_secret = os.getenv("CLIENT_SECRET"),
                    scope = os.getenv("CLIENT_SCOPE"),
                    ssl_verify = os.getenv("SSL_VERIFY")
                }

                local res, err = require("resty.openidc").authenticate(opts)

                if err then
                    ngx.status = 500
                    ngx.say(err)
                    ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
                end

                if inTable(res.user.role, "admin_kibana") == false then
                  ngx.exit(ngx.HTTP_FORBIDDEN)
                end
            ';

        proxy_pass         http://to_elk_kibana:5601;
    }
}

Another strange thing I’ve seen during my tests. Each time the browser makes a GET request on a protected App, lua-resty-openidc make a call to the OpenId Connect Provider. I don’t know if it’s a normal behavior or a settings mistake?

INTERNAL SERVER ERROR 500.

Hello there,

I get an internal server error with nothing in my logs, so it is kinda hard to debug.
My config file works without the require("resty.openidc") line.

As soon as I add this line, the whole thing crashed.

I setted : lua_package_path '/usr/local/openresty/lualib/resty/?.lua;;';
I got the openidc.lua file in the package path above.

I can't see what's wrong ..

I am quite new to this, so it might be pretty simple, I am still not sure the way I add package is the good one ..

Please help me.
Thanks in advance for your time,
Twinko5

Question: how to configure logout redirect

Hello

I am trying to 'convert' a working mod_auth_openidc configuration to lua-resty-openidc.

Login is working, and so is logout, but I cannot seem to get the OP redirect to an application page after logout

With mod_auth_openidc I could do something like "callback?logout=<redirect url", but I can's find how to configure that using the combination of 'logout_path' and 'redirect_after_logout_uri'. I guess I need to specify it in redirect_after_logout_uri but that is not really working.
Perhaps the id_token_hint is missing or something. THis is automagically provided using mod_auth_openidc.

All tips warmly welcomed!

Tx

Peter

not sure how to handle interaction_required

When using Google as an OP, I have been using opts.authorization_params.prompt = "none", in cases where I am reauthorizing a recently authorized user, but want to do so in a way that is seamless/invisible to the user.

This works well except in a few rare cases, where the user has beeb independently logged out of Google in the brief time between first authorization to my app, and the reauthorization attempt using opts.authorization_params.prompt = "none".

In those cases, Google sends back the following args (and only the following args) to the redirect url:

state=032b7b6bb5ba1daabe0abfa8eea75090  (for example)
&error_subtype=access_denied
&error=interaction_required

This, of course, throws the following error:

openidc.lua:256: authenticate(): unhandled request to the redirect_uri: /redirect_uri?state=032b7b6bb5ba1daabe0abfa8eea75090&error_subtype=access_denied&error=interaction_required

How would this best be handled? Ideally, I'd like to redirect back to Google with opts.authorization_params.prompt = nil so that the user can be prompted in this one case.

Is this kind of response something that maybe lua-resty-openidc could/should be prepared to handle?

attempt to concatenate field 'state' (a nil value)

This is working very well, except on about 10-15% of page loads (two different sites) typically after an initial successful login to the site, I am getting 500's which show up as attempt to concatenate field 'state' (a nil value) in the logs.

Here are two examples:

2016/01/10 08:41:18 [error] 20680#0: *198 lua entry thread aborted: runtime error: /opt/openresty/lualib/resty/openidc.lua:260: attempt to concatenate field 'state' (a nil value)
stack traceback:
coroutine 0:
    /opt/openresty/lualib/resty/openidc.lua: in function 'authenticate'
    access_by_lua(nginx.conf:232):11: in function <access_by_lua(nginx.conf:232):1>, client: IP_REDACTED, server: REDACTED.com, request: "GET /redirect_uri?state=1f3a05983ecad4f7c567cec9906ec613&code=4/xfw5ux-IejCSEcojEcgs-fcxqz1J6V5xF2lORuipuFw&authuser=0&hd=REDACTED.com&session_state=d9e845af3ee7ece2958d2c45dc3abf123b77a056..d752&prompt=none HTTP/1.1", host: "REDACTED.com", referrer: "https://REDACTED.com/jsp/common/login/Login.jsp;jsessionid=G1gFWSXVrTylsXdHkRTp9hRcmXKcyTfZWF8rzsmGLmpk76TwDlvj!-1484896595"
2016/01/10 07:51:27 [error] 20526#0: *14 lua entry thread aborted: runtime error: /opt/openresty/lualib/resty/openidc.lua:260: attempt to concatenate field 'state' (a nil value)
stack traceback:
coroutine 0:
    /opt/openresty/lualib/resty/openidc.lua: in function 'authenticate'
    access_by_lua(nginx.conf:188):11: in function <access_by_lua(nginx.conf:188):1>, client: IP_REDACTED, server: REDACTED.com, request: "GET /redirect_uri?state=4ff8e3db1e9490dd2e5c9e9106a211b5&code=4/W8OlE5WneQJRJ37QmKWUH_XO3EoCfGxDOKJ1FoVqZ-Y&authuser=0&hd=REDACTED.com&session_state=85ec1da20441f46f50edc2dd7b190bd96b7e4b4d..d98b&prompt=none HTTP/1.1", host: "REDACTED.com", referrer: "https://accounts.google.com/ServiceLogin?continue=https%3A%2F%2Faccounts.google.com%2Fo%2Foauth2%2Fv2%2Fauth%3Fscope%3Dopenid%2Bemail%2Bprofile%26response_type%3Dcode%26state%3D4ff8e3db1e8690dd2e5c9e9106a211b5%26redirect_uri%3Dhttps%3A%2F%2FREDACTED.com%2Fredirect_uri%26nonce%3Db58d3254d725632575716345f28b1a8b%26client_id%3DREDACTED.apps.googleusercontent.com%26hl%3Den%26from_login%3D1%26as%3D7e62210aa03c7ffe&ltmpl=popup&sacu=1&scc=1&passive=1209600&acui=0"

Add integration tests

It would be nice if some sort of integration tests were easily available in this repository, either as something created for lua-resty-openidc itself, as a Git submodule (if tests exist elsewhere) or just as a reference in the form of a link in the README.

I've been searching for some sort of official test suite for OAuth and OpenID Connect, but the only thing I've found is this, which requires setting up all kinds of user-dependent stuff on oauth.io and LinkedIn. It also didn't work after I went through the required steps, so I don't know if this is an achievable goal at all.

Access to un-parsed id_token JWT for Kubernetes OIDC integration

I'm trying to use lua-resty-openidc as an OIDC RP in front of Kubernetes. Based on the Kuberentes docs, it looks like the oidc integration requires the original jwt id_token instead of the access_token. (kubernetes/website#1209). Would there be any issues with adding the unparsed json.id_token to the session data so I can set it in the Authorization Header when proxying to k8s?

Thanks!

help w/ setting custom cookie

hi there, great library. i'm wondering if you could give me pointer to where i could modify the set cookie action. we've been using tornado to do this in the past, but this library + openresty would be much better and would align w/ more of the rest of our stack.

we have a few pages that house a dashboard on admin.prodz.imgix.com and the page makes ajax calls to an api at api.prodz.imgix.com. w/ tornado, we did a set cookie on prodz.imgix.com once google sent the user back to the redirect url. i read through the code, but it didn't jump out at me where the right edits would yield this behavior. mind giving me a push in the right direction?

constant ssl errors

I'm sure this si not related to this lib, but I'm hoping to get some direction here. Nothing's changed on my proxy that I use this lib on that enables a general purpose google auth proxy, but I'm seeing these errors after 5-10 seconds after authenticating in the debug log and it's rendering this proxy unusable.

Any clues?

2016/10/25 20:03:18 [alert] 26406#0: ignoring stale global SSL error (SSL: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt)

'check session only' or 'guest user' feature

Let me know if you are familiar with this mode of operation.

I have an application that expects REMOTE_USER from the web server. It checks the REMOTE_USER against permissions on individual pages within the application. If a page is private, the application returns 401 or 403 depending on whether REMOTE_USER is set. The web server converts 401 to a redirect to the login page.

In other words, the bulk of the application would pass a flag to openidc.authenticate() to skip the openidc_authorize() call. Instead of doing a redirect, openidc.authenticate() would return 'user not logged in': https://github.com/pingidentity/lua-resty-openidc/blob/master/lib/resty/openidc.lua#L635

The location for the login page would of course continue to do the redirect when the user was not logged in.

Issue in using UAA as OpenId provider

When using UAA the url openid configuration URL of UAA http:///uaa/.well-known/openid-configuration returns a JSON where the issuer field has value http:///uaa/oauth/token

This fails the validation in the openidc.lua and gives a error "issuer field in Discovery data does not match URL". Instead of checking for the full URL if the validation is changed to checking only for the host name then we would be able to use the script with OpenId as well.

Add validation of hd param in id_token

Step 5 of validating and ID token listed over here: https://developers.google.com/identity/protocols/OpenIDConnect#validatinganidtoken

says:

If you passed a hd parameter in the request, verify that the ID token has a hd claim that matches your Google Apps hosted domain.

It seems like this functionality is missing from openidc_validate_id_token here:

https://github.com/pingidentity/lua-resty-openidc/blob/master/lib/resty/openidc.lua#L87

Without this is seems like it's not possible to restrict login access to a particular google apps domain.

lua_ssl_trusted_certificate

This may be a daft question, but what certificate is this supposed to be?

lua_ssl_trusted_certificate /opt/local/etc/openssl/cert.pem

Clearly I am not using the right one, as this is what I see in the nginx error logs:

2016/01/10 07:12:36 [alert] 20456#0: *1 ignoring stale global SSL error (SSL: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt), client: IP_REDACTED, server: REDACTED.com, request: "GET / HTTP/1.1", host: "REDACTED.com"
2016/01/10 07:12:36 [error] 20456#0: *1 lua ssl certificate verify error: (20: unable to get local issuer certificate), client: IP_REDACTED, server: REDACTED.com, request: "GET / HTTP/1.1", host: "REDACTED.com"

Build Error Failed installing lib/resty/openidc.lua

Hi Ping Identity,
I'm just trying to set up one of our Ubuntu 14.04 Servers running Nginx up to use OpenID Connect.

It's a plain installation, I've tried installing OpenRusty (I wasn't sure if this was a requirement) and luarocks.

I can only get as far in the installation as:
lua-resty-http 0.08-0 is now built and installed in /usr/local/ (license: 2-clause BSD)
cp: cannot stat ‘lib/resty/openidc.lua’: No such file or directory

Error: Build error: Failed installing lib/resty/openidc.lua in /usr/local/lib/luarocks/rocks/lua-resty-openidc/1.2.1-1/lua/resty

Any ideas how to get past this part? I've followed the information in the readme.md

Many thanks.

"require claim" support?

Is there any way to specify if a claim is required, for example if a person has a certain value for role?

question about session cookie expiration

I am finding that some browsers don't expire session cookies even when the browser is quit an relaunched. I don't want them to persist that long.

I tried these lua-resty-session settings:

set $session_cookie_renew 600;
set $session_cookie_lifetime 3600;

But the cookie that session cookie set by lua-resty-openidc still seems to show "session" expiration, and the above settings seem to have no effect.

Am I misusing these settings, or is there perhaps a better approach to shorter term invalidation and/or expiration of lua-resty-openidc sessions?

Nginx OpenIDC with Keycloak 2.5 - Redirect Loop

Hello,

I have installed the lua-resty-openidc module in Nginx server and opensource keycloak server.

When I access any resource in Nginx it got redirect to Keycloak server for authentication. After authentication it redirect to Redirect URI and getting HTTP 500 server error. Am I missing something in the Redirect_Uri param?

http://nginxint.com:81/token?state=08621333464a7df9e995227744bc9d0a&code=grVpNleibVO_ogX5BhxEkgktuSEe83337xTrlvunkNo.458efbab-d1bf-4a98-89c0-9a958a3274b6

Returns HTTP 500 error.

Here is my opendic config.
access_by_lua '
local opts = {
-- the full redirect URI must be protected by this script and becomes:
-- ngx.var.scheme.."://"..ngx.var.http_host..opts.redirect_uri_path
-- unless the scheme is overridden using opts.redirect_uri_scheme or an X-Forwarded-Proto header in the incoming request
redirect_uri_path = "/token",
discovery = "http://keycloakint.com:8080/auth/realms/DCOS/.well-known/openid-configuration",
client_id = "NginxWS",
--client_secret = "<client_secret>"
--authorization_params = { hd="pingidentity.com" },
--scope = "openid email profile",
--iat_slack = 600,
--redirect_uri_scheme = "https",
--logout_path = "/logout",
--token_endpoint_auth_method = ["client_secret_basic"|"client_secret_post"],
--ssl_verify = "no"
}

JWT support for iat_slack/grace period

We ares using the openidc.jwt_verify function and would like add some grace period to the expiration of the tokens.

Currently there are two places where the expiration is checked:

  1. https://github.com/pingidentity/lua-resty-openidc/blob/e451ed7d076e44541740bb524389a9aa31d5ce69/lib/resty/openidc.lua#L823
    jwt:verify(opts.secret, access_token, ...)
  2. https://github.com/pingidentity/lua-resty-openidc/blob/e451ed7d076e44541740bb524389a9aa31d5ce69/lib/resty/openidc.lua#L842
    if json.exp and json.exp < ngx.time() then

I tried setting grace periods in for both of these checks and they seem redundant to me. What is the reason/edge case for 2. Could the check just be removed?

Ways to set a grace period in 1. and 2.

  1. pass {lifetime_grace_period = opts.iat_slack} as parameter Probably should just be passed in by the caller (not this library). so no change is necessary
  2. We would need to add the grace period to the check:
-- check the token expiry
  if json then
    if json.exp and json.exp + slack < ngx.time() then

Checking in this way is already being done at another place in the code: https://github.com/pingidentity/lua-resty-openidc/blob/e451ed7d076e44541740bb524389a9aa31d5ce69/lib/resty/openidc.lua#L106

Solutions to this issue:
a) remove the check in L842 completely
b) add the iat_slack to the if-clause
c) ?

What are your thoughts on this?

access_token API: error refreshing token

Hello,

Sorry, this is an error I introduced when creating the access_token API.

Whenever I call access_token (with an expired accessToken), the lua module tries to refresh the token, but without having initialized the token_endpoint URL.

I get a :

2017/05/28 20:06:42 [debug] 7#7: *13 [lua] openidc.lua:563: access_token(): refreshing expired access_token: 3c68223ff0994bcfb633776dc47847 with: 8bc1d56b7bad2b4b91f516aa6c0caf1
2017/05/28 20:06:42 [debug] 7#7: *13 [lua] openidc.lua:227: openidc_call_token_endpoint(): client_secret_basic: authorization header 'Basic bTJEaXcwUkxxSXF0aHc6REtxeURjQXVyZ0Jpc2NDYnVSUUZmZw=='
2017/05/28 20:06:42 [debug] 7#7: *13 [lua] openidc.lua:236: openidc_call_token_endpoint(): request body for token endpoint call: refresh_token=8bc1d56b7bad2b4b91f516aa6c0caf1&grant_type=refresh_token&scope=openid%20refreshToken
2017/05/28 20:06:42 [error] 7#7: *13 lua entry thread aborted: runtime error: /usr/local/openresty/luajit/share/lua/5.1/resty/http.lua:191: bad argument #1 to 'ngx_re_match' (string expected, got nil)
stack traceback:
coroutine 0:
 [C]: in function 'ngx_re_match'
 /usr/local/openresty/luajit/share/lua/5.1/resty/http.lua:191: in function 'parse_uri'
 /usr/local/openresty/luajit/share/lua/5.1/resty/http.lua:720: in function 'request_uri'
 /opt/lua-resty-openidc/lib/resty/openidc.lua:239: in function 'openidc_call_token_endpoint'
 /opt/lua-resty-openidc/lib/resty/openidc.lua:571: in function 'access_token'
 access_by_lua(nginx.conf:146):21: in function <access_by_lua(nginx.conf:146):1>, client: 172.31.0.1, server: localhost, request: "GET /api HTTP/1.1", host: "iam"
172.31.0.1 - - [28/May/2017:20:06:42 +0000] "GET /api HTTP/1.1" 500 541 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/58.0.3029.110 Chrome/58.0.3029.110 Safari/537.36"

nginx.conf extract:

    location / {

      access_by_lua '

      local opts = {
        redirect_uri_path = "/redirect_uri",
        discovery = "http://iam:9080/oidc/.well-known/openid-configuration",
        client_id = "m2Diw0RLqIqthw",
        client_secret = "DKqyDcAurgBiscCbuRQFfg",
        scope = "openid refreshToken",
        iat_slack = 600,
        redirect_uri_scheme = "http",
        logout_path = "/api/logout",
        token_endpoint_auth_method = "client_secret_basic",
        ssl_verify = "no"
      }

      local res, err = require("resty.openidc").authenticate(opts)

      if err then
      ngx.status = 500
      ngx.say(err)
      ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
      end
      ';

      root   html;
      index  index.html index.htm;
    }


    location /api {

      access_by_lua '

      local opts = {
        redirect_uri_path = "/redirect_uri",
        discovery = "http://iam:9080/oidc/.well-known/openid-configuration",
        client_id = "m2Diw0RLqIqthw",
        client_secret = "DKqyDcAurgBiscCbuRQFfg",
        scope = "openid refreshToken",
        iat_slack = 600,
        redirect_uri_scheme = "http",
        logout_path = "/api/logout",
        token_endpoint_auth_method = "client_secret_basic",
        ssl_verify = "no"
      }

      local access_token, err = require("resty.openidc").access_token(opts)

      if err then
      ngx.status = 401
      ngx.say(err)
      ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
      end

      -- set Authorization header to AT
      if access_token then
      ngx.req.set_header("Authorization", "Bearer " .. access_token)
      end
      ';

      proxy_pass http://192.168.0.13:10001/;
    }

With the previous configuration, the problem happens whenever I call http://iam/api and the token is expired.

Misleading function signature openidc_authorization_response

Hi,
I just tried to set up the project and ran into an error, that wasn't returned correctly. Below is my try at root cause analysis:
openidc_authorization_response returns ngx.redirect(session.data.original_url), session.
https://github.com/pingidentity/lua-resty-openidc/blob/master/lib/resty/openidc.lua#L363
The first ngx.redirect is nil and the second is the session-table. This matches the usual nil, err guideline and is promptly misunderstood by the caller https://github.com/pingidentity/lua-resty-openidc/blob/master/lib/resty/openidc.lua#L636 .
Thereby the example code in the README.md would contain the session as err and ngx.say would probably fail because session is a table:
https://github.com/pingidentity/lua-resty-openidc

local res, err = require("resty.openidc").authenticate(opts)

if err then
  ngx.status = 500
  ngx.say(err)
  ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end

https://github.com/pingidentity/lua-resty-openidc/blob/master/lib/resty/openidc.lua#L363

I have a working solution, but I am not yet sure it does the right thing in all cases and will hopefully make a pull-request eventually.

why `exp` is special?

The code as blow:

   if json then
      local expiry_claim = opts.expiry_claim or "expires_in"
      local ttl = json[expiry_claim]
      if expiry_claim ~= "exp" then --https://tools.ietf.org/html/rfc7662#section-2.2
        ttl = ttl - ngx.time()
      end
      openidc_cache_set("introspection", access_token, cjson.encode(json), ttl)
    end

I check https://tools.ietf.org/html/rfc7662#section-2.2 link, that's as blow:

exp
      OPTIONAL.  Integer timestamp, measured in the number of seconds
      since January 1 1970 UTC, indicating when this token will expire,
      as defined in JWT [RFC7519].

The exp is integer timestamp, isn't seconds from now.

Question about redirect_url_path

Hi,

I have a bit difficulty to get a test configuration working with Openid Connect. Everything works fine until the auth provider redirecting pages back to the Nginx /redirect_uri. The browser in /redirect_uri page with all the scope, state, code parameters returns ERR_INVALID_RESPONSE.

I must have been missing something in the configuration. Do I need to add any special Nginx/Lua configuration the /redirect_uri URL or do I need to configure a Nginx location?

Thanks in advance!

lua-resty-jwt broken, prevents lua-resty-openidc install

0.1.10 of lua-resty-jwt is broken and is preventing the installation of lua-resty-openidc. I'm not sure the best solution here, as far as I can see there is no way to specify a version that should be excluded inside a range of versions inside a rockspec file. It should be possible to change the dependency version spec to:

"lua-resty-jwt >= 0.1.5, < 0.1.10",

but this would prevent using versions of lua-resty-jwt later than 0.1.10. You could revert the change when a fix to lua-resty-jwt is released? Anyway, not too sure what to do here, thoughts?

Create Lua Rocks profile

As mentioned in #13, someone in Ping Identity should create a profile on Lua Rocks so the current rock can be moved from my personal account to something a bit more official.

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.