Bitbucket generic_oauth behind nginx

#1

Goal / Expected Bahvior:
Enable users to log into Grafana by authenticating their email with Bitbucket Oauth consumer

Environment:
Internal server running Prometheus, Grafana v6.0.1, and nginx

Grafana.ini

[server]
protocol = http
#http_port = 3000
domain = localhost
root_url = h.t.t.p/grafana.test..internal:80 #hits nginx default_server
[users]
allow_sign_up = true
auto_assign_org = true
auto_assign_org_role = Viewer
[auth.generic_oauth]
name = Bitbucket
enabled = true
allow_sign_up = true
client_id = {{consumer_id}}
client_secret = {{shhhhh}}
scopes = account email
auth_url = bitbucket{dor}org/site/oauth2/authorize #https (can’t post more than 2 urls)
token_url = bitbucket{dot}org/site/oauth2/access_token #https
api_url = api.bitbucket{dot}org/2.0/user/emails #https
allowed_domains = {{company_name}}{dot}com
team_ids = {{company_name}}
allowed_organizations = {{company_name}}
[auth.proxy]
enabled = true
header_name = X-WEBAUTH-USER #have also tried X-Email
header_property = username #have also tried email
auto_sign_up = true

nginx/sites-available/grafana:

server {
listen 80 default_server;

server_name _;

return 302 $host$request_uri;      #http

}

server {
listen 443 ssl;
server_name _;

root /usr/share/nginx/www;
index index.html index.htm;

ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers “HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES”;
ssl_certificate {{cert_path}};
ssl_certificate_key {{key_path}}

proxy_set_header X-WEBAUTH-USER $remote_user;
proxy_set_header Authorization “”;
#proxy_set_header HOST $host;
#proxy_set_header X-Forwarded-Proto $scheme;
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

location / {
proxy_pass localhost:3000/; #http
}
}

Bitbucket Oauth Consumer:

Callback URL: grafana{dot}test..internal/login/generic_oauth #https

Actual Behavior:
Visiting h.t.t.p://grafana{dot}test.{dot}internal redirects to h.t.t.p.s://grafana{dot}test{dot}{dot}internal/login
Clicking “Sign in with Bitbucket” directs to

“id.atlassian{dot}com/login?continue=…”

which is the login page which prompts for Bitbucket email and password.
Enter credentials then redirects to

“bitbucket{dot}org/site/oauth2/authorize?access_type=online&client_id=QGMjdnkKUDNAHw&redirect_uri=h.t.t.p.%3A%2F%2Fgrafana.test.{dot}internal%2Flogin%2Fgeneric_oauth&response_type=code&scope=account+email&state=fpoLKNmqvhGrodQ3ZBZalJNDoidahnK93scWJgbo0jd4%3D”

the page simply reads:

Confirm access to your account

Invalid redirect_uri

This integration is misconfigured. Contact the vendor for assistance.

Thoughts:
I’ve tried appending /grafana/ to the root_url and in nginx but was unable to get any different error code. hitting the url simply brings up {url}.internal/login which led me to not explore that avenue further since both the callback url as well as the working grafana login page don’t use /grafana/. I could be wrong about this and am open to suggestions.
Overall, after a few hours of iterations with no progress I’m at a loss as to exactly how to fix this. i can hit the API and get correct information with Insomnia so I’m thinking it has to be either Nginx not passing the headers correctly or grafana.ini setting (maybe [auth.proxy]?).
Either way I’m at a loss.

Edit: had to break links to fit under the limit for new posters. I’ve noted whether each is http or https and replaced . with {dot}. I hope this doesn’t make it too difficult to read.

#2

Update
I realized that the callback url being https:// would not hit the proxy_pass $host$request_uri line in Nginx.
Changing callback url to http:// sent me to a different login page which requested access instead of asking for my login credentials.
After granting access, I’m redirected to

https://grafana.test.{company}.internal/login/generic_oauth?state={{state}}%3D&code={{code}}

that says:

Grafana / Server Error
Sadly something went wrong

login.OAuthLogin(get info from generic_oauth)

which logs this to /grafana/grafana.log:

lvl=info msg=“state check” logger=oauth queryState={{state}} cookieState={{cookie}}

lvl=eror msg=“login.OAuthLogin(get info from generic_oauth)” logger=context userId=0 orgId=0 uname= error=“Error getting email address: {“type”: “error”, “error”: {“message”: “emails”}}”

lvl=eror msg=“Request Completed” logger=context userId=0 orgId=0 uname= method=GET path=/login/generic_oauth status=500 remote_addr=127.0.0.1 time_ms=219 size=1750 referer=https://id.atlassian.com/

#3

Got it working!

Anyone running into the same issue, here’s the final conf that worked for my setup:

Grafana.ini

protocol = http
domain = localhost
#root_url needs to hit your default_server on nginx (:80 for me) to proxy the request_uri correctly
root_url = http://{{url}}
[auth.generic_oauth]
name = Bitbucket
enabled = true
allow_sign_up = true
client_id = {{id}}
client_secret = {{secret}}
scopes = account email
auth_url = s://bitbucket{dot}org/site/oauth2/authorize
token_url = s://bitbucket{dot}org/site/oauth2/access_token
api_url = s://api.bitbucket{dot}org/2.0/user
allowed_domains = {{your_org}}{dot}com

Nginx

server {
listen 80 default_server;

server_name _;

return 302 h.t.t.p.s://$host$request_uri;

}

server {
listen 443 ssl;
server_name {{url no http prefix}};

root /usr/share/nginx/www;
index index.html index.htm;

ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers “HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES”;
ssl_certificate {{cert_path}};
ssl_certificate_key {{key_path}};

proxy_set_header X-WEBAUTH-USER $remote_user;
proxy_set_header Authorization “”;

location / {
proxy_pass h.t.t.p://localhost:3000/;
}
}

What I was doing wrong:

  • I was trying to get complicated with the Nginx conf at first, just proxy :80 to :443 without breaking the uri and let localhost do the rest.
  • Your root url in grafana.ini needs to be for your nginx location that proxy_passes uri
  • Your Callback URL for Bitbucket needs to also hit that base nginx location to proxy_pass the token along

I have no idea if this setup will work when hosting grafana under a subdirectory. Hope this helps!