Is it possible to include digest credentials in nginx conf? - nginx-reverse-proxy

I'm trying to run some automation tests against a network that requires digest authentication.
With curl I would do:
curl --digest -u user:pass -X POST -H "Content-Type: application/json" -d data https://URL
With python:
from requests.auth import HTTPDigestAuth
authentication = HTTPDigestAuth('user', 'pass')
I would like to run an nginx reverse proxy though, add the credentials there and access the network without further authentication:
server {
listen 8555;
location / {
proxy_set_header Authorization $http_authorization;
proxy_pass_header Authorization;
proxy_ssl_server_name on;
proxy_pass https://URL;
}
}
With Basic authorization you can do:
proxy_set_header Authorization "Basic a4luZzppc25ha2Vk";
But how can I do that with digest authorization?

Related

Keycloak X.509 authentication using proxy

I am trying to configure X.509 client authentication on the Keycloak 17.0.0 (Quarkus). I am using the quay.io/keycloak/keycloak:17.0.0 to deploy it in my Kubernetes environment.
I am running the Keycloak according the https://github.com/keycloak/keycloak/blob/main/docs/guides/src/main/server/reverseproxy.adoc:
/opt/keycloak/bin/kc.sh build --spi-x509cert-lookup-provider=nginx
/opt/keycloak/bin/kc.sh start-dev --spi-x509cert-lookup-nginx-ssl-client-cert=SSL_CLIENT_CERT
And I have the configuration of the X.509 client certificate authentication in the Browser and Direct Grant authentication flows, enabled in the authentication bindings, according the https://www.keycloak.org/docs/latest/server_admin/#_x509.
So expecting that the Keycloak will take the client certificate from SSL_CLIENT_CERT header and authenticate based on that.
However, trying to use the certificate to authenticate, I receive:
{
"error_description": "X509 client certificate is missing.",
"error": "invalid_request"
}
This is my curl:
curl http://localhost:8080/auth/realms/TEST/protocol/openid-connect/token \
-H "SSL_CLIENT_CERT: <cert_content>" \
-d "grant_type=password&username=&password=&client_id=CLIENT_ID&client_secret=CLIENT_SECRET"
There is a little documentation about how to do it behind the proxy in the Keycloak Quarkus version.
Anyone able to make it work?
1.) You need to use TLS, so you can't use http protocol for that - https is required. Ideal TLS config will have proper cert setup, otherwise curl will need --insecure.
2.) -H "SSL_CLIENT_CERT: <cert_content>" \ adds HTTP header, so that's is level 7 (OSI model), but TLS connection is level 4. So this is wrong.
Curl has another parameters --cert, --key for mutual (X.509) TLS. You should to have also proper data encoding, so in theory correct curl:
curl -s -X POST \
--cert /<path>/client-pem.crt \
--key /<path>/client-pem.key \
--data-urlencode "client_id=CLIENT_ID" \
--data-urlencode "client_secret=CLIENT_SECRET" \
--data-urlencode "grant_type=password" \
--data-urlencode "username=" \
--data-urlencode "password=" \
https://<keycloak-host>/auth/realms/TEST/protocol/openid-connect/token

cURL authentication with mod_auth_openidc and keycloak

I have an authentication server running Keycloak, and a Apache2 webserver with mod_auth_openidc to do OAuth2 authorization.
With browsers, I can successfully intercept access to protected resource to redirect user to Keycloak login page. After successful login, user will be redirected to the resource link.
With Postman, I can also retrieve access token JWT with password grant flow, then use the access token to access protected resource. The cURL code provided by postman indicates that the mod_auth_openidc_session cookie is also required.
Next, I try to do 2-stage cURL command in Linux CLI.
First I retrieve the access token using password grant flow as below. I initiated the cookie engine to capture session cookies given by mod_auth_openidc.
# RETRIEVE ACCESS TOKEN JSON
curl -L -b ./cookie.jar -c ./cookie.jar -d 'client_id=CLIENT_ID' -d 'client_secret=368127b1-1ee0-4f3f-8429-29e9a93daf9a' -d 'username=USERNAME' -d 'password=PASSWORD' -d 'grant_type=password' 'https://AUTH_SERVER:PORT/auth/realms/REALM/protocol/openid-connect/token
# PARSE ACCESS TOKEN
access_token=`echo $response|jq '.access_token'|cut -d\" -f2`
Next, with the access token bearer in header and cookie jar file, I try to access to the protected resource.
curl -b ./cookie.jar -c ./cookie.jar --insecure -L -X GET 'https://RESOURCE_SERVER:PORT/protected_content' --header "'Authorization: Bearer "$access_token"'"
However, I still got redirected to the Keycloak login page, and the session cookie is not recorded in the cookie jar file.
Here is the recorded cookie jar file with sensitive info redacted/replaced.
# Netscape HTTP Cookie File
# https://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
#HttpOnly_[AUTH_SERVER] FALSE /auth/realms/master/ TRUE 0 KC_RESTART eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI2Y2ZiNjYwOC1kMTlhLTQwZGUtOWJiYS04NzcxOTkzZTIwMWUifQ.eyJjaWQi[REDACTED]4aHhkVDBGZmhBZEVTSm8iLCJub25jZSI6IndTYXNYOWhGeGIxd1hKakNrS2FLMXVadVRGX3ZOZzRGVUZnMTJyYXFWbVkifX0.53645krpwlFnJ09cHAcZhNCci-DhGigu4soN5CVsZQ0
#HttpOnly_[AUTH_SERVER] FALSE /auth/realms/master/ TRUE 0 AUTH_SESSION_ID_LEGACY 6a23b139-05ba-4d22-b9e3-9ae857074814.[AUTH_SERVER]
#HttpOnly_[AUTH_SERVER] FALSE /auth/realms/master/ TRUE 0 AUTH_SESSION_ID 6a23b139-05ba-4d22-b9e3-9ae857074814.[AUTH_SERVER]
#HttpOnly_[RESOURCE_SERVER] FALSE / TRUE 0 mod_auth_openidc_state_XGEq0YKJAwSt8hxdT0FfhAdESJo NVc9Mk1FmN[REDACTED]lydKVtOw0iL-Y9iZMjzcUinutFPn74rmVvI_ERV3C8Wn1Euio8pID0jEAmu9NEfY_MEeuzOzqe6w7I20HZUNQHX0uh_vXR8
Can anyone tell me what I did wrong in the 2-stage cURL authentication/authorization process?
You have single quotes inside double quotes when setting Authorization header. This means instead of expect Authorization: Bearer token server is getting 'Authorization: Bearer token'. You can check the contents of your headers by using verbose -v option.
Following command should work as expected:
curl --header "Authorization: Bearer $access_token" -b ./cookie.jar -c ./cookie.jar --insecure -L -X GET https://RESOURCE_SERVER:PORT/protected_content'
Optionally, if you need double qoutes around token use following:
--header "Authorization: Bearer \"$access_token\""
Side note: In order not to overwrite existing cookies in cookie.jar, use different file name to store cookies from the request to authorized file.

Keycloak - invalid token when using nginx proxy

I’m trying to set up Keycloak using nginx as proxy.
The idea is to log in to web app using javascript adapter and then for each API request, nginx should ask Keycloak if token is valid (session could be revoked, etc.).
I’ve set it up without nginx locally - I have keycloak on my VM and I used Keycloak Gatekeeper to proxy API requests. It worked with no issues whatsoever.
Then, I deployed Keycloak and web app that uses js adapter on cluster and in nginx I proxied URLs required for login. Next, I configured auth module to call /auth/realms/cerulean-magnolia/protocol/openid-connect/token with grant_type=urn:ietf:params:oauth:grant-type:uma-ticket. There could be better endpoint to call but I’m always getting invalid_grant Invalid bearer token anyway.
Login works but when I try to use generated token, it becomes invalid and I can’t use it anymore.
I’ve set PROXY_ADDRESS_FORWARDING to true.
Any attempt of using this token ends up in getting:
{
"error": "invalid_grant",
"error_description": "Invalid bearer token"
}
If I would generate this token manually (via forwarded port) using password:
curl -L -X POST 'https://localhost:8141/auth/realms/cerulean-magnolia/protocol/openid-connect/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=lei' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'scope=openid' \
--data-urlencode 'username=...' \
--data-urlencode 'password=...' --insecure | jq
and then use this token to do:
http --verify=no -f https://localhost:8141/auth/realms/cerulean-magnolia/protocol/openid-connect/token grant_type=urn:ietf:params:oauth:grant-type:uma-ticket audience=lei-api response_mode=decision authorization:"Bearer ..."
It works fine. But if I use token generated via web app, I always get 401.
I’d be grateful for any help or hints.
Thanks in advance,
Patryk

How to cURL an `https://` URL from OpenShift container

Following up on my earlier question, I realized that even if I SSH into my OpenShift container and attempt to manually cURL an HTTPS URL, it seems to get internally re-routed to the HTTP equivalent. How can I actually access the HTTPS version?
From my local machine:
$ curl -X POST -H “Authorization: Basic <TOKEN>” -H “Content-Type: application/x-www-form-urlencoded” -H “Content-Length: 0” https://api.stubhub.com/login
{”error”:”invalid_request”,”error_description”:”Missing grant_type parameter value”}
And from my remote machine (via SSH):
> curl -X POST -H “Authorization: Basic <TOKEN>” -H “Content-Type: application/x-www-form-urlencoded” -H “Content-Length: 0” https://api.stubhub.com/login
<HTML><HEAD>
<TITLE>Access Denied</TITLE>
</HEAD><BODY>
<H1>Access Denied</H1>
You don't have permission to access “http://api.stubhub.com/login” on this server.<P>
Reference #18.63de6bd1.1459386064.30c676b
</BODY>
</HTML>
Note the http URL in the latter's response body.
(And of course, I'm using a working/tested <TOKEN>.)
You should contact stubhub and see if they are blocking the ip address(es) that you are attempting the connection from. I am able to curl other https url's from OpenShift Online without any issues.

How to get Authorization Token for Ceilometer API Openstack

I am new to openstack, trying to use Ceilometer python API to pull some data from a testbed server, I am accessing the server from a remote site
the problem is that I cannot figure out how get the an authorization token
I used the following command
curl -i 'http://HOST:8774/' -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d/tokens auth": {"tenantName": "project", "passwordCredentials": {"username": "user", "password": "password"}}}'
But it does not give me anything,
curl -X GET -H "X-Auth-Token:$MY_TOKEN" http://HOST:8774/tokens
also does not give me any token
From your use of port 8774 I suspect you might be using DevStack. Try this
curl -s -X POST http://$OPENSTACK_KEYSTONE_HOST:5000/v2.0/tokens -d '{"auth": {"passwordCredentials": {"username":"my-username", "password":"my-password"}, "tenantName":"my-tenantName"}}
In DevStack Keystone (the auth service you get tokens from) is running on port 5000 by default. This may or may not be true in your case. Ask your friendly OpenStack operator what host (and port) Keystone is running on and put that in place of $OPENSTACK_KEYSTONE_HOST:5000