apps/docs/content/guides/auth/social-login/auth-azure.mdx
To enable Azure (Microsoft) Auth for your project, you need to set up an Azure OAuth application and add the application credentials to your Supabase Dashboard.
Setting up OAuth with Azure consists of four broad steps:
https://<project-ref>.supabase.co/auth/v1/callbackAzure does not allow 127.0.0.1 as a redirect URI hostname and requires
the use of localhost.
To enable Azure OAuth during local Supabase development, configure the
Supabase API external URL in your config.toml:
[api]
external_url = "http://localhost:54321"
You can also configure the Azure auth provider using the Management API:
# Get your access token from https://supabase.com/dashboard/account/tokens
export SUPABASE_ACCESS_TOKEN="your-access-token"
export PROJECT_REF="your-project-ref"
# Configure Azure auth provider
curl -X PATCH "https://api.supabase.com/v1/projects/$PROJECT_REF/config/auth" \
-H "Authorization: Bearer $SUPABASE_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"external_azure_enabled": true,
"external_azure_client_id": "your-azure-client-id",
"external_azure_secret": "your-azure-client-secret",
"external_azure_url": "your-azure-url"
}'
Microsoft Entra ID can send out unverified email domains in certain cases. This may open up your project to a vulnerability where a malicious user can impersonate already existing accounts on your project.
This only applies in at least one of these cases:
authenticationBehaviors setting of your OAuth application to allow unverified email domainsThis means that most OAuth apps are not susceptible to this vulnerability.
Despite this, we recommend configuring the optional xms_edov claim on the OAuth app. This claim allows Supabase Auth to identify with certainty whether the email address sent over by Microsoft Entra ID is verified or not.
Configure this in the following way:
optionalClaims key. "optionalClaims": {
"idToken": [
{
"name": "xms_edov",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "email",
"source": null,
"essential": false,
"additionalProperties": []
}
],
"accessToken": [
{
"name": "xms_edov",
"source": null,
"essential": false,
"additionalProperties": []
}
],
"saml2Token": []
},
A Microsoft Entra tenant is the directory of users who are allowed to access your project. This section depends on what your OAuth registration uses for Supported account types.
By default, Supabase Auth uses the common Microsoft tenant (https://login.microsoftonline.com/common) which generally allows any Microsoft account to sign in to your project. Microsoft Entra further limits what accounts can access your project depending on the type of OAuth application you registered.
If your app is registered as Personal Microsoft accounts only for the Supported account types set Microsoft tenant to consumers (https://login.microsoftonline.com/consumers).
If your app is registered as My organization only for the Supported account types you may want to configure Supabase Auth with the organization's tenant URL. This will use the tenant's authorization flows instead, and will limit access at the Supabase Auth level to Microsoft accounts arising from only the specified tenant.
Configure this by storing a value under Azure Tenant URL in the Supabase Auth provider configuration page for Azure that has the following format https://login.microsoftonline.com/<tenant-id>.
Supabase Auth requires that Azure returns a valid email address. Therefore you must request the email scope in the signInWithOAuth method.
<Tabs scrollable size="small" type="underlined" defaultActiveId="js" queryGroup="language"
<TabPanel id="js" label="JavaScript">
<$Partial path="create_client_snippet.mdx" />
When your user signs in, call signInWithOAuth() with azure as the provider:
import { createClient } from '@supabase/supabase-js'
const supabase = createClient('https://your-project.supabase.co', 'sb_publishable_... or anon key')
// ---cut---
async function signInWithAzure() {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'azure',
options: {
scopes: 'email',
},
})
}
When your user signs in, call signInWithOAuth() with azure as the provider:
Future<void> signInWithAzure() async {
await supabase.auth.signInWithOAuth(
OAuthProvider.azure,
redirectTo: kIsWeb ? null : 'my.scheme://my-host', // Optionally set the redirect link to bring back the user via deeplink.
authScreenLaunchMode:
kIsWeb ? LaunchMode.platformDefault : LaunchMode.externalApplication, // Launch the auth screen in a new webview on mobile.
);
}
When your user signs in, call signInWith(Provider) with Azure as the Provider:
suspend fun signInWithAzure() {
supabase.auth.signInWith(Azure) {
scopes.add("email")
}
}
<$Partial path="oauth_pkce_flow.mdx" />
<Tabs scrollable size="small" type="underlined" defaultActiveId="js" queryGroup="language"
<TabPanel id="js" label="JavaScript">
When your user signs out, call signOut() to remove them from the browser session and any objects from localStorage:
import { createClient } from '@supabase/supabase-js'
const supabase = createClient('https://your-project.supabase.co', 'sb_publishable_... or anon key')
// ---cut---
async function signOut() {
const { error } = await supabase.auth.signOut()
}
When your user signs out, call signOut() to remove them from the browser session and any objects from localStorage:
Future<void> signOut() async {
await supabase.auth.signOut();
}
When your user signs out, call signOut() to remove them from the browser session and any objects from localStorage:
suspend fun signOut() {
supabase.auth.signOut()
}
Azure OAuth2.0 doesn't return the provider_refresh_token by default. If you need the provider_refresh_token returned, you will need to include the following scope:
<Tabs scrollable size="small" type="underlined" defaultActiveId="js" queryGroup="language"
<TabPanel id="js" label="JavaScript">
import { createClient } from '@supabase/supabase-js'
const supabase = createClient('https://your-project.supabase.co', 'sb_publishable_... or anon key')
// ---cut---
async function signInWithAzure() {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: 'azure',
options: {
scopes: 'offline_access',
},
})
}
Future<void> signInWithAzure() async {
await supabase.auth.signInWithOAuth(
OAuthProvider.azure,
scopes: 'offline_access',
);
}
suspend fun signInWithAzure() {
supabase.auth.signInWith(Azure) {
scopes.add("offline_access")
}
}