oauth2-proxy: Unable to set `username` when using Keycloak provider
I am setting up the following environment:
User | Nginx | Oauth2 <—> Keycloak | Grafana
This is the nginx configuration (following the example here):
server {
listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
ssl_certificate /etc/nginx/ssl/nginx_vas_cz.crt;
ssl_certificate_key /etc/nginx/ssl/nginx_vas_cz.key;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
location /grafana/ {
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
# pass information about the user to the backend
# requires oauth2-proxy to run with --set-xauthrequest flag
auth_request_set $user $upstream_http_x_auth_request_user;
auth_request_set $email $upstream_http_x_auth_request_email;
auth_request_set $name $upstream_http_x_auth_request_preferred_username;
proxy_set_header X-Username $user;
proxy_set_header X-Email $email;
proxy_set_header X-Name $name;
proxy_pass http://grafana.vas.cz:3000/;
}
location /oauth2/ {
proxy_pass http://oauth.vas.cz:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Auth-Request-Redirect $request_uri;
}
location = /oauth2/auth {
proxy_pass http://oauth.vas.cz:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
# nginx auth_request includes headers but not body
proxy_set_header Content-Length "";
proxy_pass_request_body off;
}
}
When I access https://nginx.vas.cz/grafana/, I get redirected to Keycloak login page, perform the login and then sent to Grafana, but without login.
If I change proxy_set_header X-Username $user; to proxy_set_header X-Username "<new user>"; (in other words I force the login user), the user gets created in Grafana with the following profile:
- Name =
<my email> - Email =
<my email> - Username =
<new user>
which tells me that everything is correctly configured (or I will not be able to login).
According to your documentation, the --set-xauthorequest option should enable the following headers: X-Auth-Request-User, X-Auth-Request-Email and X-Auth-Request-Preferred-Username, so apparently the X-Auth-Request-User is not resolved.
This is the authentication result I get in the oauth2-proxy log:
[2020/07/17 14:10:45] [requests.go:26] 200 GET http://keycloak.vas.cz:8080/auth/realms/tutorial01/protocol/openid-connect/userinfo {"sub":"f4bb8645-f16f-4237-a9e4-58dea9e046f7","email_verified":false,"name":"<name surname>","groups":["/admin"],"preferred_username":"<username>","given_name":"<name>","family_name":"<surname>","email":"<email>"}
192.168.56.5:57446 - <email> [2020/07/17 14:10:45] [AuthSuccess] Authenticated via OAuth2: %!s(PANIC=String method: runtime error: invalid memory address or nil pointer dereference)
[2020/07/17 14:10:45] [cookies.go:48] Warning: request host "nginx.vas.cz" did not match any of the specific cookie domains of ""
Keycloak is returning all the expected information from the user.
So, I tried a different test:
proxy_set_header X-Username "newuser";
proxy_set_header X-User-Email "email";
proxy_set_header X-User-Name "name";
and again the user gets created with
- Name = “name”
- Email = “email”
- Username = “newuser”
Putting together the two tests:
$upstream_http_x_auth_request_email = <email in KC> OK
$upstream_http_x_auth_request_preferred_username = <email in KC>, which is wrong. Note how the “preferred_username” in KC reply is the “<username>”, not the email.
$upstream_http_x_auth_request_user is resolved to <email in KC> too. To verify this, I made the following test:
proxy_set_header X-Username "new_user";
proxy_set_header X-User-Email $email;
proxy_set_header X-User-Name $user;
and I got the user created with “Name” = "<email>".
This is my configuration for oauth2:
./oauth2/oauth2-proxy --provider=keycloak --client-id=oauth2 --client-secret=<secret> --login-url="http://keycloak.vas.cz:8080/auth/realms/tutorial01/protocol/openid-connect/auth" --redeem-url="http://keycloak.vas.cz:8080/auth/realms/tutorial01/protocol/openid-connect/token" --validate-url="http://keycloak.vas.cz:8080/auth/realms/tutorial01/protocol/openid-connect/userinfo" --keycloak-group=/admin --email-domain=* --cookie-secret=<secret> --http-address="http://192.168.56.8:4180" --scope=openid --set-xauthrequest=true
Expected Behavior
$upstream_http_x_auth_request_email = <email in KC> OK
$upstream_http_x_auth_request_preferred_username = <preferred username in KC> i.e. the shortname uid
$upstream_http_x_auth_request_user = <name surname> i.e. the “name” filed in KC response.
Current Behavior
Everything is apparently mapped to the user’s email
Update: apparently, after further investigation, it seems that $upstream_http_x_auth_request_preferred_username and $upstream_http_x_auth_request_user are not returned at all.
Possible Solution
Steps to Reproduce (for bugs)
The above should be enough. Let me know if you need something more.
Context
I’m setting authentication behind a authorization proxy.
Your Environment
- Version used: oauth2-proxy v6.0.0 (built with go1.14.2)
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 3
- Comments: 31 (12 by maintainers)
Please reopen. This is still happening.
if I log in and go to oauth2/userinfo I get
This is kinda huge and breaking
Still an issue…
The oauth2-proxy keycloak interface
To enable this, the session needs the fields filling in when it is created, I would recommend taking a look at how this is done in the OIDC provider for guidance
If I go to
oauth2/userinfoI am gettingwhich is different from what @insanemal is getting, is seemingly random string in
userfield, andgroupsmissingAs per request above, the following headers are returned at
.../oauth2/auth. Does the keycloak provider-settings only look at the headers and ignore the data in thex-auth-request-access-token?In my case, for troubleshooting, I am running with
pass_access_token = true, but noX-Forwarded-Access-Tokenis set despite this. I have an instance ofmendhak/http-https-echoset up which echoes all headers sent to the page, which when set up behind the oatuth2-proxy imho should include more than just thex-auth-request-emailwhen it comes to user data, but this is all that is set.The panic issue should be resolved as of v6.1.1. If you upgrade to this version the session information should print correctly which will allow us to see which parts of the session are populated which I believe will help to narrow down the issue
I have the same issue with the following setup:
User | Ingress Nginx | Oauth2 <—> Keycloak 11.0.1 | Rundeck
Username and
x-forwarded-userare always empty with provider keycloak. I also had to create a specific client scope in keycloak named “api” to avoid the following blocking error :Invalid scope: apiIf I use Gitlab/OIDC providers, username is filled. I tried with v6.1.1 and
stefansedich:group-claimforkShould you be interested in the environment I used to reproduce, you can find it detailed here.
I think there may be a bug within the Keycloak provider, it should be returning a username but your comment suggests that the username is empty. We need to look at where it is constructing the session and see why the username isn’t being populated there.