1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-11-25 22:32:57 +02:00

Microsoft Entra ID provider (#2390)

* Microsoft Entra ID Provider

* fix typo in function name

* documentation tweaks

* documentation and comment tweak

* docs tweaks

* final tweaks

* refactor: drop flag for skipping graph groups

* update legacy / deprecated provider page and sort provider overview

* reformat

* move entra-id provider into switch (treat like every other provider

* fix test case and reformat

* fix sidebar configuration

* apply review suggestions

* add pagination for graph api

* fix: do not error when groups unable to retrieve

* doc: number of groups fix

* restore master packages

* docs: tiny docs tweak

* address review comments

* fix codegen

---------

Co-authored-by: tuunit <jan@larwig.com>
This commit is contained in:
JJ Łakis
2024-12-31 12:46:13 +01:00
committed by GitHub
parent c64ec1251b
commit 5f188e5b6b
14 changed files with 617 additions and 51 deletions

View File

@@ -385,6 +385,16 @@ character.
| `default` | _[]string_ | _(Optional)_ Default specifies a default value or values that will be<br/>passed to the IdP if not overridden. |
| `allow` | _[[]URLParameterRule](#urlparameterrule)_ | _(Optional)_ Allow specifies rules about how the default (if any) may be<br/>overridden via the query string to `/oauth2/start`. Only<br/>values that match one or more of the allow rules will be<br/>forwarded to the IdP. |
### MicrosoftEntraIDOptions
(**Appears on:** [Provider](#provider))
| Field | Type | Description |
| ----- | ---- | ----------- |
| `allowedTenants` | _[]string_ | AllowedTenants is a list of allowed tenants. In case of multi-tenant apps, incoming tokens are<br/>issued by different issuers and OIDC issuer verification needs to be disabled.<br/>When not specified, all tenants are allowed. Redundant for single-tenant apps<br/>(regular ID token validation matches the issuer). |
### OIDCOptions
(**Appears on:** [Provider](#provider))
@@ -418,6 +428,7 @@ Provider holds all configuration for a single provider
| `clientSecretFile` | _string_ | ClientSecretFile is the name of the file<br/>containing the OAuth Client Secret, it will be used if ClientSecret is not set. |
| `keycloakConfig` | _[KeycloakOptions](#keycloakoptions)_ | KeycloakConfig holds all configurations for Keycloak provider. |
| `azureConfig` | _[AzureOptions](#azureoptions)_ | AzureConfig holds all configurations for Azure provider. |
| `microsoftEntraIDConfig` | _[MicrosoftEntraIDOptions](#microsoftentraidoptions)_ | MicrosoftEntraIDConfig holds all configurations for Entra ID provider. |
| `ADFSConfig` | _[ADFSOptions](#adfsoptions)_ | ADFSConfig holds all configurations for ADFS provider. |
| `bitbucketConfig` | _[BitbucketOptions](#bitbucketoptions)_ | BitbucketConfig holds all configurations for Bitbucket provider. |
| `githubConfig` | _[GitHubOptions](#githuboptions)_ | GitHubConfig holds all configurations for GitHubC provider. |

View File

@@ -1,18 +0,0 @@
---
id: azure_ad
title: Microsoft Azure AD
---
## Config Options
| Flag | Toml Field | Type | Description | Default |
| ---------------- | -------------- | ------ | ---------------------------------------------------------------- | ---------- |
| `--azure-tenant` | `azure_tenant` | string | go to a tenant-specific or common (tenant-independent) endpoint. | `"common"` |
| `--resource` | `resource` | string | The resource that is protected (Azure AD only) | |
## Usage
For adding an application to the Microsoft Azure AD follow [these steps to add an application](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app).
Take note of your `TenantId` if applicable for your situation. The `TenantId` can be used to override the default
`common` authorization server with a tenant specific server.

View File

@@ -3,6 +3,10 @@ id: gitea
title: Gitea
---
:::note
This is not actually its own provider. For more details and options please refer to the [GitHub Provider Options](github.md)
:::
1. Create a new application: `https://< your gitea host >/user/settings/applications`
2. Under `Redirect URI` enter the correct URL i.e. `https://<proxied host>/oauth2/callback`
3. Note the Client ID and Client Secret.

View File

@@ -8,21 +8,22 @@ with Redirect URI(s) for the domain you intend to run `oauth2-proxy` on.
Valid providers are :
- [Google](google.md) _default_
- [Azure](azure.md)
- [ADFS](adfs.md)
- [Facebook](facebook.md)
- [GitHub](github.md)
- [Gitea](gitea.md)
- [Keycloak](keycloak.md)/[Keycloak OIDC](keycloak_oidc.md)
- [GitLab](gitlab.md)
- [LinkedIn](linkedin.md)
- [Microsoft Azure AD](azure_ad.md)
- [OpenID Connect](openid_connect.md)
- [login.gov](login_gov.md)
- [Nextcloud](nextcloud.md)
- [DigitalOcean](digitalocean.md)
- [Bitbucket](bitbucket.md)
- [DigitalOcean](digitalocean.md)
- [Facebook](facebook.md)
- [Gitea](gitea.md)
- [GitHub](github.md)
- [GitLab](gitlab.md)
- [Google](google.md) _default_
- [Keycloak](keycloak.md) (Deprecated)
- [Keycloak OIDC](keycloak_oidc.md)
- [LinkedIn](linkedin.md)
- [login.gov](login_gov.md)
- [Microsoft Azure](ms_azure_ad.md) (Deprecated)
- [Microsoft Entra ID](ms_entra_id.md)
- [Nextcloud](nextcloud.md)
- [OpenID Connect](openid_connect.md)
The provider can be selected using the `provider` configuration value.

View File

@@ -1,10 +1,10 @@
---
id: keycloak
title: Keycloak
title: Keycloak (Deprecated)
---
:::note
This is the legacy provider for Keycloak, use [Keycloak OIDC Auth Provider](keycloak_oidc.md) if possible.
This is the legacy and deprecated provider for Keycloak, use [Keycloak OIDC Auth Provider](keycloak_oidc.md) if possible.
:::
1. Create new client in your Keycloak realm with **Access Type** 'confidential' and **Valid Redirect URIs** 'https://internal.yourcompany.com/oauth2/callback'

View File

@@ -1,8 +1,12 @@
---
id: azure
title: Azure
title: Azure (Deprecated)
---
:::note
This is the legacy and deprecated provider for Azure, use [Microsoft Entra ID](ms_entra_id.md) if possible.
:::
## Config Options
| Flag | Toml Field | Type | Description | Default |

View File

@@ -0,0 +1,158 @@
---
id: ms_entra_id
title: Microsoft Entra ID
---
Provider for Microsoft Entra ID. Fully compliant with OIDC, with support for group overage and multi-tenant apps.
## Config Options
The provider is OIDC-compliant, so all the OIDC parameters are honored. Additional provider-specific configuration parameters are:
| Flag | Toml Field | Type | Description | Default |
| --------------------------- | -------------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `--entra-id-allowed-tenant` | `entra_id_allowed_tenants` | string \| list | List of allowed tenants. In case of multi-tenant apps, incoming tokens are issued by different issuers and OIDC issuer verification needs to be disabled. When not specified, all tenants are allowed. Redundant for single-tenant apps (regular ID token validation matches the issuer). | |
## Configure App registration
To begin, create an App registration, set a redirect URI, and generate a secret. All account types are supported, including single-tenant, multi-tenant, multi-tenant with Microsoft accounts, and Microsoft accounts only.
<details>
<summary>See Azure Portal example</summary>
<div class="videoBlock">
<iframe src="https://www.youtube.com/embed/IUNfxhOzr4E"></iframe>
</div>
</details>
<details>
<summary>See Terraform example</summary>
```
resource "azuread_application" "auth" {
display_name = "oauth2-proxy"
sign_in_audience = "AzureADMyOrg" # Others are also supported
web {
redirect_uris = [
"https://podinfo.lakis.tech/oauth2/callback",
]
}
// We don't specify any required API permissions - we allow user consent only
}
resource "azuread_service_principal" "sp" {
client_id = azuread_application.auth.client_id
app_role_assignment_required = false
}
resource "azuread_service_principal_password" "pass" {
service_principal_id = azuread_service_principal.sp.id
}
```
</details>
### Configure groups
If you want to make use of groups, you can configure *groups claim* to be present in ID Tokens issued by the App registration.
<details>
<summary>See Azure Portal example</summary>
<div class="videoBlock">
<div class="videoBlock">
<iframe src="https://www.youtube.com/embed/QZmP5MKEJis"></iframe>
</div>
</div>
</details>
<details>
<summary>See Terraform example</summary>
```
resource "azuread_application" "auth" {
display_name = "oauth2-proxy"
sign_in_audience = "AzureADMyOrg"
group_membership_claims = [
"SecurityGroup"
]
web {
redirect_uris = [
"https://podinfo.lakis.tech/oauth2/callback",
]
}
}
resource "azuread_service_principal" "sp" {
client_id = azuread_application.auth.client_id
app_role_assignment_required = false
}
resource "azuread_service_principal_password" "pass" {
service_principal_id = azuread_service_principal.sp.id
}
```
</details>
### Scopes and claims
For single-tenant and multi-tenant apps without groups, the only required scope is `openid` (See: [Scopes and permissions](https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc#the-openid-scope)).
To make use of groups - for example use `allowed_groups` setting or authorize based on groups inside your service - you need to enable *groups claims* in the App Registration. When enabled, list of groups is present in the issued ID token. No additional scopes are required besides `openid`. This works up to 200 groups.
When user has more than 200 group memberships, OAuth2-Proxy attempts to retrieve the complete list from Microsoft Graph API's [`transitiveMemberOf`](https://learn.microsoft.com/en-us/graph/api/user-list-transitivememberof). Endpoint requires `User.Read` scope (delegated permission). This permission can be by default consented by user during first login. Set scope to `openid User.Read` to request user consent. Without proper scope, user with 200+ groups will authenticate with 0 groups. See: [group overages](https://learn.microsoft.com/en-us/security/zero-trust/develop/configure-tokens-group-claims-app-roles#group-overages).
Alternatively to user consent, both `openid` and `User.Read` permissions can be consented by admistrator. Then, user is not asked for consent on the first login, and group overage works with `openid` scope only. Admin consent can also be required for some tenants. It can be granted with [azuread_service_principal_delegated_permission_grant](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/service_principal_delegated_permission_grant) terraform resource.
For personal microsoft accounts, required scope is `openid profile email`.
See: [Overview of permissions and consent in the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/permissions-consent-overview).
### Multi-tenant apps
To authenticate apps from multiple tenants (including personal Microsoft accounts), set the common OIDC issuer url and disable verification:
```toml
oidc_issuer_url=https://login.microsoftonline.com/common/v2.0
insecure_oidc_skip_issuer_verification=true
```
`insecure_oidc_skip_issuer_verification` setting is required to disable following checks:
* Startup check for matching issuer URL returned from [discovery document](https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration) with `oidc_issuer_url` setting. Required, as document's `issuer` field doesn't equal to `https://login.microsoftonline.com/common/v2.0`. See [OIDC Discovery 4.3](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationValidation).
* Matching ID token's `issuer` claim with `oidc_issuer_url` setting during ID token validation. Required to support tokens issued by diffrerent tenants. See [OIDC Core 3.1.3.7](https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation).
To provide additional security, Entra ID provider performs check on the ID token's `issuer` claim to match the `https://login.microsoftonline.com/{tenant-id}/v2.0` template.
### Example configurations
Single-tenant app without groups (*groups claim* not enabled). Consider using generic OIDC provider:
```toml
provider="entra-id"
oidc_issuer_url="https://login.microsoftonline.com/<tenant-id>/v2.0"
client_id="<client-id>"
client_secret="<client-secret>"
scope="openid"
```
Single-tenant app with up to 200 groups (*groups claim* enabled). Consider using generic OIDC provider:
```toml
provider="entra-id"
oidc_issuer_url="https://login.microsoftonline.com/<tenant-id>/v2.0"
client_id="<client-id>"
client_secret="<client-secret>"
scope="openid"
allowed_groups=["ac51800c-2679-4ecb-8130-636380a3b491"]
```
Single-tenant app with more than 200 groups:
```toml
provider="entra-id"
oidc_issuer_url="https://login.microsoftonline.com/<tenant-id>/v2.0"
client_id="<client-id>"
client_secret="<client-secret>"
scope="openid User.Read"
allowed_groups=["968b4844-d5e7-4e18-a834-59927959369f"]
```
Multi-tenant app with Microsoft personal accounts & one Entra tenant allowed, with group overage considered:
```toml
provider="entra-id"
oidc_issuer_url="https://login.microsoftonline.com/common/v2.0"
client_id="<client-id>"
client_secret="<client-secret>"
insecure_oidc_skip_issuer_verification=true
scope="openid profile email User.Read"
entra_id_allowed_tenant=["9188040d-6c67-4c5b-b112-36a304b66dad","<my-tenant-id>"] # Allow only <my-tenant-id> and Personal MS Accounts tenant
email_domains="*"
```

View File

@@ -31,22 +31,22 @@ const sidebars = {
id: 'configuration/providers/index',
},
items: [
'configuration/providers/google',
'configuration/providers/azure',
'configuration/providers/adfs',
'configuration/providers/facebook',
'configuration/providers/github',
'configuration/providers/gitea',
'configuration/providers/keycloak',
'configuration/providers/keycloak_oidc',
'configuration/providers/gitlab',
'configuration/providers/linkedin',
'configuration/providers/azure_ad',
'configuration/providers/openid_connect',
'configuration/providers/login_gov',
'configuration/providers/nextcloud',
'configuration/providers/digitalocean',
'configuration/providers/bitbucket',
"configuration/providers/adfs",
"configuration/providers/azure",
"configuration/providers/bitbucket",
"configuration/providers/digitalocean",
"configuration/providers/facebook",
"configuration/providers/gitea",
"configuration/providers/github",
"configuration/providers/gitlab",
"configuration/providers/google",
"configuration/providers/keycloak",
"configuration/providers/keycloak_oidc",
"configuration/providers/linkedin",
"configuration/providers/login_gov",
"configuration/providers/ms_entra_id",
"configuration/providers/nextcloud",
"configuration/providers/openid_connect",
],
},
'configuration/session_storage',

View File

@@ -23,3 +23,17 @@
margin: 0 calc(-1 * var(--ifm-pre-padding));
padding: 0 var(--ifm-pre-padding);
}
.videoBlock {
position: relative;
padding-bottom: 75%;
height: 0;
}
.videoBlock iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}