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

Azure AD support #290

Closed
tomsmyers opened this issue Jul 8, 2020 · 10 comments
Closed

Azure AD support #290

tomsmyers opened this issue Jul 8, 2020 · 10 comments

Comments

@tomsmyers
Copy link
Contributor

tomsmyers commented Jul 8, 2020

i'm working on an integration with azure AD. after a successful login, vouch unpacks the body of the OIDC /userinfo response into a structs.User object, which takes values from fields username, email etc.

if err = json.Unmarshal(data, user); err != nil {

when constructing the jwt to store, the claims are constructed using this structs.User.Username.

later when checking the token in /validate, vouch checks if the username is populated and returns 401 if is not.

if claims.Username == "" {

this logic makes the assumption that username is included in the /userinfo response, which in my case it is not. 😞

is there a way to take information like this from the ID token instead of the /userinfo response? in azure AD, i can't configure which fields are included in the /userinfo response (e.g. to add the user's email address), but i can configure which fields are included in the tokens.

vouch config for posterity:

VOUCH_JWT_MAXAGE=20
VOUCH_ALLOWALLUSERS=true
VOUCH_LOGLEVEL=debug
VOUCH_COOKIE_SECURE=false
VOUCH_COOKIE_DOMAIN=localhost

OAUTH_PROVIDER=oidc
OAUTH_CLIENT_ID=...
OAUTH_CLIENT_SECRET=...
OAUTH_BASEURL=https://login.microsoftonline.com/...
OAUTH_AUTH_URL=https://login.microsoftonline.com/.../oauth2/v2.0/authorize
OAUTH_TOKEN_URL=https://login.microsoftonline.com/.../oauth2/v2.0/token
OAUTH_USER_INFO_URL=https://graph.microsoft.com/oidc/userinfo
OAUTH_SCOPES=openid,profile,email
OAUTH_CALLBACK_URLS=http://localhost:9090/auth
@tomsmyers tomsmyers changed the title openid provider makes assumptions about claims included in userinfo response oidc provider makes assumptions about claims included in userinfo response Jul 8, 2020
@bnfinet
Copy link
Member

bnfinet commented Jul 8, 2020

@tomsmyers have you tried using the adfs provider? IIRC it uses the same interfaces as Azure AD. A quick view of the adfs.go code shows it falling back to using the UPN if an email isn't present.

https://github.com/vouch/vouch-proxy/blob/master/config/config.yml_example_adfs

@bnfinet bnfinet changed the title oidc provider makes assumptions about claims included in userinfo response oidc provider userinfo response expects u.Username, breaks Azure AD if it isn't populated Jul 8, 2020
@tomsmyers
Copy link
Contributor Author

unfortunately using the adfs provider does not work with azure AD; you get the error The 'resource' request parameter is not supported. when redirecting to the login page.

@bnfinet
Copy link
Member

bnfinet commented Jul 9, 2020

@simongottschlag do you have any insight into Azure AD setups? ^^

@tomsmyers if you'd care to add a new provider at providers/azure/azure.go I'd be happy to accept a PR. I'm not a user of Azure so I'm not in a position to test/support Azure AD at this time.

@bnfinet bnfinet changed the title oidc provider userinfo response expects u.Username, breaks Azure AD if it isn't populated Azure AD support Jul 9, 2020
@simongottschlag
Copy link
Contributor

@bnfinet Azure AD has their own quirks compared to ADFS. The resource query parameter is required with ADFS to populate the claims correctly while causing issues with Azure AD.

There are also differences with using Azure AD with a single tenant and using the “multi-tenant” endpoints and may require additional configuration to get both working.

@tomsmyers
Copy link
Contributor Author

thanks for the comments, i opened a PR to add support for my azure ad config by simply mapping upn claim to username and email (based on the docs, upn is an email address), unless the fields already exist in the token.

#292

bnfinet added a commit that referenced this issue Jul 10, 2020
@bnfinet
Copy link
Member

bnfinet commented Jul 10, 2020

@tomsmyers thanks much for the addition to VP!

@sintaxx
Copy link

sintaxx commented Mar 8, 2021

Has anyone any documentation on how to setup Vouch with Azure AD sitting behind an nginx reverse proxy ? This would be amazing.

@jastlw
Copy link

jastlw commented Dec 23, 2022

@simongottschlag Can I also configure azure_token through environmental variables for OAuth config?

I want to use it with docker compose:

vouch-proxy:
    container_name: ex-vouch
    image: voucher/vouch-proxy:alpine
    restart: unless-stopped
    volumes:
      - nginx-config-data/vouch:/config
    enviroment:
      - VOUCH_DOMAINS=vouch.dockertest1.azurewebsites.net
      - VOUCH_ALLOWALLUSERS=true
      - VOUCH_COOKIE_DOMAIN=dockertest1.azurewebsites.net
      - VOUCH_SESSION_KEY=********
      - OAUTH_PROVIDER=azure
      - OAUTH_CLIENT_ID=123456789
      - OAUTH_CLIENT_SECRET=********
      - OAUTH_AUTH_URL=https://login.microsoftonline.com/.../oauth2/v2.0/authorize
      - OAUTH_TOKEN_URL=https://login.microsoftonline.com/.../oauth2/v2.0/token
      - OAUTH_SCOPES=openid,profile,email
      - OAUTH_CALLBACK_URL=https://dockertest1.azurewebsites.net/auth
      - OAUTH_AZURE_TOKEN=id_token

With reference to #320
I think I am not sure yet, if I really need to set the "OAUTH_AZURE_TOKEN".

Thank you in advance.

@bnfinet
Copy link
Member

bnfinet commented Dec 23, 2022

@jastlw it should but that may have been overlooked when we implemented config via environmental variables.

Could you please test that, and open a new issue if it does not work?

@jastlw
Copy link

jastlw commented Jul 26, 2023

@bnfinet I forgot to give the feedback: it is working. :)

      - VOUCH_ALLOWALLUSERS=true
      - VOUCH_COOKIE_DOMAIN=domain.de
      - VOUCH_SESSION_KEY=***
      - OAUTH_PROVIDER=azure
      - OAUTH_CLIENT_ID=********-****-****-****-***************
      - OAUTH_CLIENT_SECRET=**********
      - OAUTH_AUTH_URL=https://login.microsoftonline.com/********-****-****-****-***************/oauth2/v2.0/authorize
      - OAUTH_TOKEN_URL=https://login.microsoftonline.com/********-****-****-****-***************/oauth2/v2.0/token
      - OAUTH_USER_INFO_URL=https://graph.microsoft.com/oidc/userinfo
      - OAUTH_SCOPES=openid,profile,email
      - OAUTH_CALLBACK_URL=https://vouch.domain.de/auth
      - OAUTH_AZURE_TOKEN=id_token
      - VIRTUAL_HOST=vouch.domain.de
      - VIRTUAL_PORT=9090
      - LETSENCRYPT_HOST=vouch.domain.de
      - LETSENCRYPT_EMAIL=admin@domain.de
      - VOUCH_LOGLEVEL=debug

@sintaxx I used nginx-proxy with the following configs as Per-VIRTUAL_HOST and Per-VIRTUAL_HOST location configuration
app.domain.de

# send all requests to the `/validate` endpoint for authorization
auth_request /validate;

location = /validate {
  # forward the /validate request to Vouch Proxy
  proxy_pass http://vouch.domain.de/validate;

  # be sure to pass the original host header
  proxy_set_header Host $http_host;

  # Vouch Proxy only acts on the request headers
  proxy_pass_request_body off;
  proxy_set_header Content-Length "";

  # optionally add X-Vouch-User as returned by Vouch Proxy along with the request
  auth_request_set $auth_resp_x_vouch_user $upstream_http_x_vouch_user;

  # these return values are used by the @error401 call
  auth_request_set $auth_resp_jwt $upstream_http_x_vouch_jwt;
  auth_request_set $auth_resp_err $upstream_http_x_vouch_err;
  auth_request_set $auth_resp_failcount $upstream_http_x_vouch_failcount;
}

# if validate returns `401 not authorized` then forward the request to the error401 block
error_page 401 = @error401;

location @error401 {
  # redirect to Vouch Proxy for login
  return 302 https://vouch.domain.de/login?url=$scheme://$http_host$request_uri&vouch-failcount=$auth_resp_failcount&X-Vouch-Token=$auth_resp_jwt&error=$auth_resp_err;
}

app.domain.de_location

  # you may need to set these variables in this block as per https://github.com/vouch/vouch-proxy/issues/26#issuecomment-425215810
  # auth_request_set $auth_resp_x_vouch_user $upstream_http_x_vouch_user
  # auth_request_set $auth_resp_x_vouch_idp_claims_groups $upstream_http_x_vouch_idp_claims_groups;
  # auth_request_set $auth_resp_x_vouch_idp_claims_given_name $upstream_http_x_vouch_idp_claims_given_name;

  # set user header (usually an email)
  proxy_set_header X-Vouch-User $auth_resp_x_vouch_user;
  # optionally pass any custom claims you are tracking
  # proxy_set_header X-Vouch-IdP-Claims-Groups $auth_resp_x_vouch_idp_claims_groups;
  # proxy_set_header X-Vouch-IdP-Claims-Given_Name $auth_resp_x_vouch_idp_claims_given_name;
  # optionally pass the access token or id token
  # proxy_set_header X-Vouch-IdP-AccessToken $auth_resp_x_vouch_idp_accesstoken;
  # proxy_set_header X-Vouch-IdP-IdToken $auth_resp_x_vouch_idp_idtoken;

Thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants