Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to do strict issuer verification #44

Closed
chris-crunchr opened this issue Apr 19, 2023 · 27 comments
Closed

Unable to do strict issuer verification #44

chris-crunchr opened this issue Apr 19, 2023 · 27 comments

Comments

@chris-crunchr
Copy link

According to the example apache config, I can force strict issuer verification with the verify.iss=required option. However, when I set this option to required it fails, while it succeeds with optional.

My config looks like this:

OAuth2TokenVerify metadata https://<domain>/.well-known/openid-configuration metadata.ssl_verify=false&verify.iss=required

One interesting excerpt from the logs:

[Wed Apr 19 11:53:49.360956 2023] [oauth2:debug] [pid 110463:tid 140637177321216] src/jose.c(1040): [client 127.0.0.1:52514] _oauth2_jose_jwt_validate_iss: enter: iss=(null), validate=required

This suggests to me that the value of iss is not passed along.

I'm using KeyCloak as my IdP and verified that the iss field in token corresponds with the issuer field in the metadata.

@chris-crunchr
Copy link
Author

chris-crunchr commented Apr 19, 2023

Looked a bit further into it and found the one (and only) call site of _oauth2_jose_jwt_validate_iss here, which in turn seems to be only called from here. The latter call site hardcodes the iss parameter to NULL. Then in _oauth2_jose_jwt_validate_iss there is an explicit NULL check on iss, causing this behavior AFAIK.

As far as I understand the code, the iss parameter should be the value from the metadata.

@zandbelt
Copy link
Member

it was not implemented yet, since the most common configs don't provide this value, but issuer validation when the verification was configured through metadata was just added; thanks for reporting and digging in!

@chris-crunchr
Copy link
Author

Awesome! I was sifting through the code to find a way to fix it, but you fixed it before I could even find a suitable starting point. Thanks!

@zandbelt
Copy link
Member

edit: it needed 44a3892 as well...

@chris-crunchr
Copy link
Author

Is it possible for you to create a new release with this patch? Or provide details on how to do it myself? I'm trying to create a deb myself, but its a bit finicky. Also, it would help us track the exact version used.

@chris-crunchr
Copy link
Author

This is great! Thanks again! 🙏

@chris-crunchr
Copy link
Author

Not entirely sure how this works. I see the release jobs are finished, but there is no new item on the release page. Should I just wait, or is there a step missing?

@zandbelt
Copy link
Member

hold on, still building...

@zandbelt
Copy link
Member

@chris-crunchr
Copy link
Author

Ah, thought the release job in github actions was enough. Thanks!

@chris-crunchr
Copy link
Author

Finally got a round testing this, but it still seems broken! I get the exact same message as before (iss=(null), validate=required). Double checked I'm actually using 1.5.1.

@zandbelt
Copy link
Member

are you sure there is an "Issuer" value in the configured metadata document? if so, can you debug trace what happens?

@chris-crunchr
Copy link
Author

Verified it and keycloak does provide a issuer key in the metadata (is the uppercase relevant?). Anyway, tried to isolate the relevant logs as much as possible and ran it again with LogLevel trace3 and got this:

[Tue May 02 14:36:53 2023] [rewrite:trace2] mod_rewrite.c(483): 127.0.0.1 - - [<DOMAIN>/sid#7ffa79c6c4b8][rid#7ffa7a6140a0/initial] init rewrite engine with requested uri /api/cdsf
[Tue May 02 14:36:53 2023] [rewrite:trace3] mod_rewrite.c(483): 127.0.0.1 - - [<DOMAIN>/sid#7ffa79c6c4b8][rid#7ffa7a6140a0/initial] applying pattern '^' to uri '/api/cdsf'
[Tue May 02 14:36:53 2023] [rewrite:trace3] mod_rewrite.c(483): 127.0.0.1 - - [<DOMAIN>/sid#7ffa79c6c4b8][rid#7ffa7a6140a0/initial] applying pattern '^/xyz(.*)' to uri '/api/cdsf'
[Tue May 02 14:36:53 2023] [rewrite:trace3] mod_rewrite.c(483): 127.0.0.1 - - [<DOMAIN>/sid#7ffa79c6c4b8][rid#7ffa7a6140a0/initial] applying pattern '^/xyz(.*)' to uri '/api/cdsf'
[Tue May 02 14:36:53 2023] [rewrite:trace1] mod_rewrite.c(483): 127.0.0.1 - - [<DOMAIN>/sid#7ffa79c6c4b8][rid#7ffa7a6140a0/initial] pass through /api/cdsf
[Tue May 02 14:36:53 2023] [proxy:trace2] mod_proxy.c(687): AH03461: attempting to match URI path '/api/cdsf' against prefix '/auth' for proxying
[Tue May 02 14:36:53 2023] [proxy:trace2] mod_proxy.c(687): AH03461: attempting to match URI path '/api/cdsf' against prefix '/' for proxying
[Tue May 02 14:36:53 2023] [proxy:trace1] mod_proxy.c(773): AH03464: URI path '/api/cdsf' matches proxy handler 'proxy:http://localhost:3305/api/cdsf'
[Tue May 02 14:36:53 2023] [authz_core:debug] mod_authz_core.c(817): AH01626: authorization result of Require valid-user : denied (no authenticated user yet)
[Tue May 02 14:36:53 2023] [authz_core:debug] mod_authz_core.c(817): AH01626: authorization result of <RequireAny>: denied (no authenticated user yet)
[Tue May 02 14:36:53 2023] [auth_kerb:debug] src/mod_auth_kerb.c(1963): kerb_authenticate_user entered with user (NULL) and auth_type oauth2
[Tue May 02 14:36:53 2023] [oauth2:debug] src/http.c(158): _oauth2_http_request_header_set_add_sanitized: Host: <DOMAIN>
[Tue May 02 14:36:53 2023] [oauth2:debug] src/http.c(158): _oauth2_http_request_header_set_add_sanitized: User-Agent: curl/7.68.0
[Tue May 02 14:36:53 2023] [oauth2:debug] src/http.c(158): _oauth2_http_request_header_set_add_sanitized: Accept: */*
[Tue May 02 14:36:53 2023] [oauth2:debug] src/http.c(158): _oauth2_http_request_header_set_add_sanitized: Authorization: Bearer <TOKEN>
[Tue May 02 14:36:53 2023] [oauth2:debug] src/server/apache.c(326): oauth2_apache_request_context_init: created request context: 0x7ffa580024d0
[Tue May 02 14:36:53 2023] [oauth2:debug] src/mod_oauth2.c(179): oauth2_check_user_id_handler: incoming request: "/api/cdsf?(null)" ap_is_initial_req=1
[Tue May 02 14:36:53 2023] [oauth2:debug] src/mod_oauth2.c(98): oauth2_request_handler: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/proto.c(212): _oauth2_get_source_token_from_envvar: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/server/apache.c(538): oauth2_apache_get_envvar: get environment variable: access_token
[Tue May 02 14:36:53 2023] [oauth2:debug] src/proto.c(224): _oauth2_get_source_token_from_envvar: no source token found in access_token environment variable
[Tue May 02 14:36:53 2023] [oauth2:debug] src/proto.c(45): _oauth2_get_source_token_from_header: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/util.c(921): oauth2_nv_list_get: Authorization=Bearer <TOKEN>
[Tue May 02 14:36:53 2023] [oauth2:debug] src/proto.c(58): _oauth2_get_source_token_from_header: Authorization header found
[Tue May 02 14:36:53 2023] [oauth2:debug] src/proto.c(84): _oauth2_get_source_token_from_header: leave: <TOKEN>
[Tue May 02 14:36:53 2023] [oauth2:debug] src/oauth2.c(827): oauth2_token_verify: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache.c(316): oauth2_cache_get: enter: key=<TOKEN>, type=shm, decrypt=0
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache.c(235): _oauth2_cache_hash_key: enter: key=<TOKEN>, algo=(null)
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(122): oauth2_jose_hash_bytes: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(172): oauth2_jose_hash_bytes: leave: 1
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache.c(250): _oauth2_cache_hash_key: leave: hashed key: 47fdb4ba22fee58acadeefd08e1e2d23240c5c9fe9bfe4f13144e353b2c7833a
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache/shm.c(254): oauth2_cache_shm_get: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache/shm.c(317): oauth2_cache_shm_get: leave: 1
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache.c(350): oauth2_cache_get: leave: cache miss for key: <TOKEN> return: 0 bytes
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(2078): oauth2_jose_resolve_from_uri: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache.c(316): oauth2_cache_get: enter: key=https://<DOMAIN>/auth/realms/<REALM>/.well-known/openid-configuration, type=shm, decrypt=0
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache.c(235): _oauth2_cache_hash_key: enter: key=https://<DOMAIN>/auth/realms/<REALM>/.well-known/openid-configuration, algo=(null)
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(122): oauth2_jose_hash_bytes: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(172): oauth2_jose_hash_bytes: leave: 1
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache.c(250): _oauth2_cache_hash_key: leave: hashed key: 988bd6a77b65d86eb21429e5bf0534bac3381240086903f0166641b4b6571e4b
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache/shm.c(254): oauth2_cache_shm_get: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache/shm.c(282): oauth2_cache_shm_get: found: 988bd6a77b65d86eb21429e5bf0534bac3381240086903f0166641b4b6571e4b (expires=1683103349, now=1683031013)
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache/shm.c(289): oauth2_cache_shm_get: not expired: 988bd6a77b65d86eb21429e5bf0534bac3381240086903f0166641b4b6571e4b
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache/shm.c(317): oauth2_cache_shm_get: leave: 1
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache.c(350): oauth2_cache_get: leave: cache hit for key: https://<DOMAIN>/auth/realms/<REALM>/.well-known/openid-configuration return: 6716 bytes
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(2125): oauth2_jose_resolve_from_uri: leave: {"issuer":"https://<DOMAIN>/auth/realms/<REALM>", ... }
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(974): oauth2_jose_jwt_header_peek: decoding: <TOKEN> (1425-1314=111)
[Tue May 02 14:36:53 2023] [oauth2:debug] src/util.c(165): _oauth2_cjose_base64_decode: enter: len=111
[Tue May 02 14:36:53 2023] [oauth2:debug] src/util.c(189): _oauth2_cjose_base64_decode: leave: len=83
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(984): oauth2_jose_jwt_header_peek: decoded: {"alg":"RS256","typ" : "JWT","kid" : "yhMjOwJxUyc9xTtTdqKGwwQxmDSoTBGUcKdEvTwLBrg"}
[Tue May 02 14:36:53 2023] [oauth2:debug] src/oauth2.c(526): _oauth2_metadata_verify_callback: JWT token: header={"alg":"RS256","typ" : "JWT","kid" : "yhMjOwJxUyc9xTtTdqKGwwQxmDSoTBGUcKdEvTwLBrg"}
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(974): oauth2_jose_jwt_header_peek: decoding: <TOKEN> (1425-1314=111)
[Tue May 02 14:36:53 2023] [oauth2:debug] src/util.c(165): _oauth2_cjose_base64_decode: enter: len=111
[Tue May 02 14:36:53 2023] [oauth2:debug] src/util.c(189): _oauth2_cjose_base64_decode: leave: len=83
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(984): oauth2_jose_jwt_header_peek: decoded: {"alg":"RS256","typ" : "JWT","kid" : "yhMjOwJxUyc9xTtTdqKGwwQxmDSoTBGUcKdEvTwLBrg"}
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(1253): oauth2_jose_jwt_verify: enter: JWT token header={"alg":"RS256","typ" : "JWT","kid" : "yhMjOwJxUyc9xTtTdqKGwwQxmDSoTBGUcKdEvTwLBrg"}
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(2078): oauth2_jose_resolve_from_uri: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache.c(316): oauth2_cache_get: enter: key=https://<DOMAIN>/auth/realms/<REALM>/protocol/openid-connect/certs, type=shm, decrypt=0
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache.c(235): _oauth2_cache_hash_key: enter: key=https://<DOMAIN>/auth/realms/<REALM>/protocol/openid-connect/certs, algo=(null)
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(122): oauth2_jose_hash_bytes: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(172): oauth2_jose_hash_bytes: leave: 1
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache.c(250): _oauth2_cache_hash_key: leave: hashed key: 79dc4e24341451581fadfecf57d0862bcfb581e440a511aa25ba131122526923
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache/shm.c(254): oauth2_cache_shm_get: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache/shm.c(282): oauth2_cache_shm_get: found: 79dc4e24341451581fadfecf57d0862bcfb581e440a511aa25ba131122526923 (expires=1683103350, now=1683031013)
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache/shm.c(289): oauth2_cache_shm_get: not expired: 79dc4e24341451581fadfecf57d0862bcfb581e440a511aa25ba131122526923
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache/shm.c(317): oauth2_cache_shm_get: leave: 1
[Tue May 02 14:36:53 2023] [oauth2:debug] src/cache.c(350): oauth2_cache_get: leave: cache hit for key: https://<DOMAIN>/auth/realms/<REALM>/protocol/openid-connect/certs return: 2989 bytes
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(2125): oauth2_jose_resolve_from_uri: leave: {"keys":[<KEYS>]}
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(2024): _oauth2_jose_jwks_uri_resolve_response_callback: skipping key because of non-matching "use": "enc"
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(924): _oauth2_jose_jwt_verify_jwk: enter: jws kid=yhMjOwJxUyc9xTtTdqKGwwQxmDSoTBGUcKdEvTwLBrg, jwk kid=yhMjOwJxUyc9xTtTdqKGwwQxmDSoTBGUcKdEvTwLBrg
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(936): _oauth2_jose_jwt_verify_jwk: cjose_jws_verify returned true
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(949): _oauth2_jose_jwt_verify_jwk: leave: rc=1
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(1317): oauth2_jose_jwt_verify: got plaintext (len=727): <PLAIN_TOKEN>
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(1206): _oauth2_jose_jwt_payload_validate: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(1040): _oauth2_jose_jwt_validate_iss: enter: iss=(null), validate=required
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(1080): _oauth2_jose_jwt_validate_iss: leave: 0
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(1231): _oauth2_jose_jwt_payload_validate: leave: 0
[Tue May 02 14:36:53 2023] [oauth2:debug] src/jose.c(1348): oauth2_jose_jwt_verify: leave: 0
[Tue May 02 14:36:53 2023] [oauth2:debug] src/oauth2.c(312): _oauth2_introspect_verify: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/http.c(807): _oauth2_http_url_encode_list: processing: token=<TOKEN>
[Tue May 02 14:36:53 2023] [oauth2:debug] src/util.c(280): oauth2_url_encode: enter: token
[Tue May 02 14:36:53 2023] [oauth2:debug] src/util.c(305): oauth2_url_encode: leave: token
[Tue May 02 14:36:53 2023] [oauth2:debug] src/util.c(280): oauth2_url_encode: enter: <TOKEN>
[Tue May 02 14:36:53 2023] [oauth2:debug] src/util.c(305): oauth2_url_encode: leave: <TOKEN>
[Tue May 02 14:36:53 2023] [oauth2:debug] src/http.c(807): _oauth2_http_url_encode_list: processing: token_type_hint=access_token
[Tue May 02 14:36:53 2023] [oauth2:debug] src/util.c(280): oauth2_url_encode: enter: token_type_hint
[Tue May 02 14:36:53 2023] [oauth2:debug] src/util.c(305): oauth2_url_encode: leave: token_type_hint
[Tue May 02 14:36:53 2023] [oauth2:debug] src/util.c(280): oauth2_url_encode: enter: access_token
[Tue May 02 14:36:53 2023] [oauth2:debug] src/util.c(305): oauth2_url_encode: leave: access_token
[Tue May 02 14:36:53 2023] [oauth2:debug] src/http.c(883): oauth2_http_url_form_encode: data=token=<TOKEN>&token_type_hint=access_token
[Tue May 02 14:36:53 2023] [oauth2:debug] src/http.c(979): oauth2_http_call: enter: url=https://<DOMAIN>/auth/realms/<REALM>/protocol/openid-connect/token/introspect, data=token=<TOKEN>&token_type_hint=access_token, ctx=[ ssl_verify=false hdr=[ Content-Type=application/x-www-form-urlencoded ] cookie=[ ] ]
[Tue May 02 14:36:53 2023] [oauth2:debug] src/http.c(1102): oauth2_http_call: HTTP response code=401
[Tue May 02 14:36:53 2023] [oauth2:debug] src/http.c(1120): oauth2_http_call: leave [1]: {"error":"invalid_request","error_description":"Authentication failed."}
[Tue May 02 14:36:53 2023] [oauth2:debug] src/oauth2.c(394): _oauth2_introspect_verify: leave: 0
[Tue May 02 14:36:53 2023] [oauth2:debug] src/oauth2.c(867): oauth2_token_verify: leave: 0
[Tue May 02 14:36:53 2023] [oauth2:debug] src/server/apache.c(368): oauth2_apache_return_www_authenticate: enter
[Tue May 02 14:36:53 2023] [oauth2:debug] src/server/apache.c(460): oauth2_apache_hdr_out_add: WWW-Authenticate: Bearer error="invalid_token", error_description="Token could not be verified."
[Tue May 02 14:36:53 2023] [oauth2:debug] src/server/apache.c(392): oauth2_apache_return_www_authenticate: leave
[Tue May 02 14:36:53 2023] [oauth2:debug] src/mod_oauth2.c(144): oauth2_request_handler: leave
[Tue May 02 14:36:53 2023] [core:trace3] request.c(117): auth phase 'check user' gave status 401: /api/cdsf
[Tue May 02 14:36:53 2023] [http:trace3] http_filters.c(1125): Response sent with status 401
[Tue May 02 14:36:53 2023] [oauth2:debug] src/server/apache.c(335): oauth2_apache_request_context_free: dispose request context: 0x7ffa580024d0

@zandbelt
Copy link
Member

zandbelt commented May 2, 2023

that really looks like you're still on 1.5.0, can you check the info log message at startup?

@chris-crunchr
Copy link
Author

Very strange. Seems like you're right, it even says mod_oauth2-3.3.1-liboauth2-1.4.5.3, while apt tells me I've 1.5.1 on my system! Thanks for taking a look, let me see if I can solve it from here.

@chris-crunchr
Copy link
Author

Something is still off. Since there is no easy way to verify whether I have the expected version of the libraries, I did the following:

  • Looked up the library loaded by apache: cat /etc/apache2/mods-enabled/oauth2.load
  • Checked which oauth2 libraries it uses: ldd /usr/lib/apache2/modules/mod_oauth2.so | grep liboauth2
  • Can't really verify the version from the .so alone. But I can reasonably guess it by comparing it to the output of dpkg-query -L liboauth2{,-apache} and verifying their md5sums (downloaded the 1.5.1 release again, extracted the DEBIAN/md5sums file and compared it against the md5sums I found).

This all checks out. So, I believe I have installed the correct version, AFAIK.

@zandbelt
Copy link
Member

zandbelt commented May 2, 2023

the log info output is leading, you still have another version on your system

@chris-crunchr
Copy link
Author

chris-crunchr commented May 2, 2023

Thats strange, because I bootstrapped a clean server and got this problem! 🤔

P.S.
I tried to find anything that could get in the way with find /usr -name '*oauth2*', but only found the libraries I expected (hashes lined up with the 1.5.1 distribution).

@zandbelt
Copy link
Member

zandbelt commented May 2, 2023

wget https://github.com/OpenIDC/liboauth2/releases/download/v1.5.1/liboauth2_1.5.1-1.bullseye_amd64.deb
apt-get install ./liboauth2_1.5.1-1.bullseye_amd64.deb
strings /usr/lib/x86_64-linux-gnu/liboauth2.so.0.0.0 | grep liboauth2
liboauth2.so.0
liboauth2-1.5.1

@chris-crunchr
Copy link
Author

Can reproduce my situation with docker:

FROM httpd:2.4

ENV DEBIAN_FRONTEND=noninteractive

RUN apt update && apt install -y wget

WORKDIR /tmp

RUN wget https://github.com/OpenIDC/mod_oauth2/releases/download/v3.3.1/libapache2-mod-oauth2_3.3.1-1.bullseye_amd64.deb \
         https://github.com/OpenIDC/liboauth2/releases/download/v1.5.1/liboauth2-apache_1.5.1-1.bullseye_amd64.deb \
         https://github.com/OpenIDC/liboauth2/releases/download/v1.5.1/liboauth2_1.5.1-1.bullseye_amd64.deb \
    && apt-get install -y \
         ./liboauth2_1.5.1-1.bullseye_amd64.deb \
         ./liboauth2-apache_1.5.1-1.bullseye_amd64.deb \
         ./libapache2-mod-oauth2_3.3.1-1.bullseye_amd64.deb

Build this with docker build . -t liboauth2-poc (podman works too). Then create the following apache2 config:

ServerRoot "/usr/local/apache2"
Listen 80

# Set info
ServerAdmin me@localhost
ServerName localhost:80

# Load modules
LoadModule mpm_event_module modules/mod_mpm_event.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule dir_module modules/mod_dir.so

# Use www-data user/group
<IfModule unixd_module>
  User www-data
  Group www-data
</IfModule>

# Deny root
<Directory />
    AllowOverride none
    Require all denied
</Directory>

# Document root
DocumentRoot "/usr/local/apache2/htdocs"

# Logging
ErrorLog /proc/self/fd/2
LogLevel debug
<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    CustomLog /proc/self/fd/1 common
</IfModule>


# Oauth2 PoC
LogLevel oauth2:trace3
LoadModule oauth2_module /usr/lib/apache2/modules/mod_oauth2.so

OAuth2TokenVerify metadata https://<auth_server>/<path/to/.well-known/openid-configuration> verify.iss=optional

<Directory "/usr/local/apache2/htdocs">
  AuthType oauth2
  Require valid-user
</Directory>

Change the metadata url to something you can create tokens for (I used a cloud-iam account). Now run this setup with docker run --rm --name liboauth2-test -v $PWD/my-httpd.conf:/usr/local/apache2/conf/httpd.conf -p 127.0.0.1:8081:80 liboauth2-poc.

For this PoC, I used client credentials and got a token with this oneliner: token=$(curl --data-urlencode grant_type=client_credentials -u client:password https://<auth_server>/<path/to/protocol/openid-connect/token> | jq -r .access_token).

Finally, I used curl -H "Authorization: Bearer $token" localhost:8081 to get access (you should get a <html><body><h1>It works!</h1></body></html> response).

Now change the verify.iss parameter to required. Then rerun the server and try the curl request again. It will show a 401 error. Also note, that when stopping the server it says oauth2_apache_parent_cleanup: mod_oauth2-3.3.1-liboauth2-1.4.5.3 - shutdown, even though I definitely installed version 1.5.1 in the image, as you can see in the docker file!

P.S. I found that the parameter values (skip, optional, required) can be fragile! For example, setting this to require instead of required will not do what you expect!

@zandbelt
Copy link
Member

ok, thanks for putting in the effort in reproducing this! I will try this and get back to you asap

@zandbelt
Copy link
Member

well, firstly it seems the compiler optimized away the runtime version reporting so it reports the version of liboauth2 compiled against rather than running against...; the liboauth2 package seems to be OK, but the issue seems to be with mod_oauth2 (3.3.1).

it doesn't explain why the issuer verification doesn't work but recompiling against that version does change things... whilst I'm trying to wrap my head around the latter, you can use a version of mod_auth2 that was recompiled against 1.5.1 here: https://www.mod-auth-openidc.org/downloads/libapache2-mod-oauth2_3.3.1-1.bullseye_amd64.deb

@chris-crunchr
Copy link
Author

Cool, will try that as soon as I can and report back here (might take a while).

@chris-crunchr
Copy link
Author

Forgot that I can quickly verify with my PoC version. Did that and it works! Its really confusing though, as the file names suggest its the same file, but I can't reproduce the bug with this "other" version. :)

@zandbelt
Copy link
Member

thanks for helping and and sorry that it took this effort; I can't explain yet why "the other" version works since it is the same code compiled against a different version of the library and the whole idea of the library is that it can be developed and deployed independently of the module using it (the API did not change); I'll look into it in the coming days and let you know what I find

@zandbelt
Copy link
Member

it turns out to be a liboauth2 packaging error for the Debian based platforms: the liboauth2.so.0 files were packaged, but not the .so files so the compilation of dependent modules such as mod_oauth2 would fallback to static linking; I will have to issue new releases for all to make sure this gets out of the way once and for all; thank you for helping to sort this out

@zandbelt
Copy link
Member

see #46 as a final note

zandbelt added a commit to OpenIDC/mod_oauth2 that referenced this issue Oct 25, 2023
depend on liboauth2 >= 1.5.1; see
OpenIDC/liboauth2#44

Signed-off-by: Hans Zandbelt <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants