Skip to content

Commit c99f867

Browse files
authored
docs: Add Microsoft Identity Provider (#418)
1 parent d016d05 commit c99f867

File tree

15 files changed

+616
-2
lines changed

15 files changed

+616
-2
lines changed
Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
# Setup
2+
3+
To set up **Sign in with Microsoft**, you must create an app registration on [Microsoft Entra ID (formerly Azure AD)](https://portal.azure.com/) and configure your Serverpod application accordingly.
4+
5+
:::caution
6+
You need to install the auth module before you continue, see [Setup](../../setup).
7+
:::
8+
9+
## Create your Microsoft Entra ID App
10+
11+
1. Go to [Microsoft Azure Portal](https://portal.azure.com/) and log in with your Microsoft account.
12+
2. Navigate to **Microsoft Entra ID** from the portal menu.
13+
14+
![Register App](/img/authentication/providers/microsoft/1-register-app.png)
15+
16+
3. Go to **App registrations** and click **New registration**.
17+
18+
![New App Registration](/img/authentication/providers/microsoft/2-register-new-app.png)
19+
20+
4. Fill in the required fields:
21+
- **Name**: Enter a name for your application (e.g., "MyApp Authentication").
22+
- **Supported account types**: Choose one of the following:
23+
- Single tenant only - Default Directory
24+
- Multiple Entra ID tenants
25+
- Any Entra ID Tenant + Personal Microsoft accounts
26+
- Personal accounts only
27+
- **Redirect URI (optional)**: Leave this blank for now. We'll add platform-specific URIs later.
28+
29+
![Microsoft App Setup](/img/authentication/providers/microsoft/3-ms.png)
30+
31+
5. Click **Register** to create your app.
32+
33+
## Get app credentials
34+
35+
### Get the client ID
36+
37+
After registration, you'll be redirected to the app overview page where you can find your **Application (client) ID**. Copy this value - you'll need it for server configuration.
38+
39+
![Client ID](/img/authentication/providers/microsoft/4-client-id.png)
40+
41+
### Create a client secret
42+
43+
1. In your app's menu, navigate to **Certificates & secrets**.
44+
2. Under **Client secrets**, click **New client secret**.
45+
46+
![Create Client Secret](/img/authentication/providers/microsoft/5-create-client-secret.png)
47+
48+
3. Add a description (e.g., "Serverpod Authentication") and choose an expiration period.
49+
4. Click **Add** and immediately copy the **Value** (not the Secret ID). This is your **Client Secret**.
50+
51+
:::warning
52+
The client secret value is only shown once. Store it securely immediately after creation. Never commit this value to version control.
53+
:::
54+
55+
### Get the tenant ID (Optional)
56+
57+
If you're restricting authentication to a specific tenant, you'll need your **Directory (tenant) ID**, which is also shown on the app overview page. For most applications, you can use one of these common values:
58+
59+
- `common`: Allows both personal Microsoft accounts and work/school accounts (default).
60+
- `organizations`: Allows only work/school accounts.
61+
- `consumers`: Allows only personal Microsoft accounts.
62+
63+
### Configure redirect URIs
64+
65+
You need to configure redirect URIs for each platform you want to support.
66+
67+
1. In your app's menu, navigate to **Authentication**.
68+
2. Click **Add a platform** to configure platform-specific settings.
69+
70+
![Authentication Redirect](/img/authentication/providers/microsoft/6-authentication-redirect-uri.png)
71+
72+
#### Web
73+
74+
1. Select **Web** as the platform.
75+
2. Add your redirect URI, typically in the format: `https://yourdomain.com/auth.html`
76+
77+
![Web Redirect URI](/img/authentication/providers/microsoft/7-web-redirect-uri.png)
78+
79+
3. Click **Configure**.
80+
81+
#### iOS and macOS
82+
83+
1. Select **iOS / macOS** as the platform.
84+
2. For the Bundle ID, enter your app's bundle identifier (e.g., `com.yourcompany.yourapp`).
85+
86+
![iOS/macOS Redirect URI](/img/authentication/providers/microsoft/8-ios-macos-redirect-uri.png)
87+
88+
3. Click **Configure**.
89+
90+
:::note
91+
For iOS/macOS, Microsoft will automatically generate the redirect URI based on your bundle ID. You can also add custom redirect URIs as needed.
92+
:::
93+
94+
#### Android
95+
96+
1. Select **Android** as the platform.
97+
2. Enter your Package name (e.g., `com.yourcompany.yourapp`).
98+
3. Enter your Signature hash. You can get this by running:
99+
100+
```bash
101+
keytool -exportcert -alias SIGNATURE_ALIAS -keystore PATH_TO_KEYSTORE | openssl sha1 -binary | openssl base64
102+
```
103+
104+
![Android Redirect URI](/img/authentication/providers/microsoft/9-android-redirect-uri.png)
105+
106+
4. Click **Configure**.
107+
108+
:::tip
109+
For development, use your debug keystore signature hash. For production builds, use your release keystore signature hash. You can add both to Microsoft Entra ID during setup.
110+
:::
111+
112+
## Server-side configuration
113+
114+
### Store the credentials
115+
116+
Add your Microsoft credentials to the `config/passwords.yaml` file, or set them as environment variables `SERVERPOD_PASSWORD_microsoftClientId`, `SERVERPOD_PASSWORD_microsoftClientSecret`, and `SERVERPOD_PASSWORD_microsoftTenant`.
117+
118+
```yaml
119+
development:
120+
microsoftClientId: 'YOUR_MICROSOFT_CLIENT_ID'
121+
microsoftClientSecret: 'YOUR_MICROSOFT_CLIENT_SECRET'
122+
microsoftTenant: 'common' # or 'organizations', 'consumers', or your specific tenant ID
123+
```
124+
125+
:::warning
126+
Keep your Client Secret confidential. Never commit this value to version control. Store it securely using environment variables or secret management.
127+
:::
128+
129+
### Configure the Microsoft Identity Provider
130+
131+
In your main `server.dart` file, configure the Microsoft identity provider:
132+
133+
```dart
134+
import 'package:serverpod/serverpod.dart';
135+
import 'package:serverpod_auth_idp_server/core.dart';
136+
import 'package:serverpod_auth_idp_server/providers/microsoft.dart';
137+
138+
void run(List<String> args) async {
139+
final pod = Serverpod(
140+
args,
141+
Protocol(),
142+
Endpoints(),
143+
);
144+
145+
pod.initializeAuthServices(
146+
tokenManagerBuilders: [
147+
JwtConfigFromPasswords(),
148+
],
149+
identityProviderBuilders: [
150+
MicrosoftIdpConfig(
151+
clientId: pod.getPassword('microsoftClientId')!,
152+
clientSecret: pod.getPassword('microsoftClientSecret')!,
153+
tenant: pod.getPassword('microsoftTenant') ?? 'common',
154+
),
155+
],
156+
);
157+
158+
await pod.start();
159+
}
160+
```
161+
162+
:::tip
163+
You can use `MicrosoftIdpConfigFromPasswords()` to automatically load credentials from `config/passwords.yaml` or the `SERVERPOD_PASSWORD_microsoftClientId`, `SERVERPOD_PASSWORD_microsoftClientSecret`, and `SERVERPOD_PASSWORD_microsoftTenant` environment variables:
164+
165+
```dart
166+
identityProviderBuilders: [
167+
MicrosoftIdpConfigFromPasswords(),
168+
],
169+
```
170+
171+
:::
172+
173+
### Expose the endpoint
174+
175+
Create an endpoint that extends `MicrosoftIdpBaseEndpoint` to expose the Microsoft authentication API:
176+
177+
```dart
178+
import 'package:serverpod_auth_idp_server/providers/microsoft.dart';
179+
180+
class MicrosoftIdpEndpoint extends MicrosoftIdpBaseEndpoint {}
181+
```
182+
183+
### Generate and migrate
184+
185+
Finally, run `serverpod generate` to generate the client code and create a migration to initialize the database for the provider. More detailed instructions can be found in the general [identity providers setup section](../../setup#identity-providers-configuration).
186+
187+
### Basic configuration options
188+
189+
- `clientId`: Required. The Application (client) ID of your Microsoft Entra ID app.
190+
- `clientSecret`: Required. The Client Secret generated for your Microsoft Entra ID app.
191+
- `tenant`: Optional. Defaults to `'common'`. Can be `'common'`, `'organizations'`, `'consumers'`, or a specific tenant ID.
192+
193+
For more details on configuration options, see the [configuration section](./configuration).
194+
195+
## Client-side configuration
196+
197+
Add the `serverpod_auth_idp_flutter` package to your Flutter app. The Microsoft provider uses [`flutter_web_auth_2`](https://pub.dev/packages/flutter_web_auth_2) to handle the OAuth2 flow, so any documentation there should also apply to this setup.
198+
199+
### iOS and macOS
200+
201+
There is no special configuration needed for iOS and macOS for "normal" authentication flows.
202+
However, if you are using **Universal Links** on iOS, they require redirect URIs to use **https**.
203+
Follow the instructions in the [flutter_web_auth_2](https://pub.dev/packages/flutter_web_auth_2#ios) documentation.
204+
205+
### Android
206+
207+
In order to capture the callback URL, add the following activity to your `AndroidManifest.xml`. Replace `YOUR_CALLBACK_URL_SCHEME_HERE` and `YOUR_CALLBACK_URL_HOST_HERE` with your actual callback URL scheme and host registered in your Microsoft Entra ID app.
208+
209+
```xml
210+
<manifest>
211+
<application>
212+
213+
<activity
214+
android:name="com.linusu.flutter_web_auth_2.CallbackActivity"
215+
android:exported="true"
216+
android:taskAffinity="">
217+
<intent-filter android:label="Microsoft Authentication">
218+
<action android:name="android.intent.action.VIEW" />
219+
<category android:name="android.intent.category.DEFAULT" />
220+
<category android:name="android.intent.category.BROWSABLE" />
221+
<data
222+
android:scheme="YOUR_CALLBACK_URL_SCHEME_HERE"
223+
android:host="YOUR_CALLBACK_URL_HOST_HERE" />
224+
</intent-filter>
225+
</activity>
226+
227+
</application>
228+
</manifest>
229+
```
230+
231+
### Web
232+
233+
On the web, you need a specific endpoint to capture the OAuth2 callback. To set this up, create an HTML file (e.g., `auth.html`) inside your project's `./web` folder and add the following content:
234+
235+
```html
236+
<!DOCTYPE html>
237+
<title>Authentication complete</title>
238+
<p>Authentication is complete. If this does not happen automatically, please close the window.</p>
239+
<script>
240+
function postAuthenticationMessage() {
241+
const message = {
242+
'flutter-web-auth-2': window.location.href
243+
};
244+
245+
if (window.opener) {
246+
window.opener.postMessage(message, window.location.origin);
247+
window.close();
248+
} else if (window.parent && window.parent !== window) {
249+
window.parent.postMessage(message, window.location.origin);
250+
} else {
251+
localStorage.setItem('flutter-web-auth-2', window.location.href);
252+
window.close();
253+
}
254+
}
255+
256+
postAuthenticationMessage();
257+
</script>
258+
```
259+
260+
:::note
261+
You only need a single callback file (e.g. `auth.html`) in your `./web` folder.
262+
This file is shared across all IDPs that use the OAuth2 utility, as long as your redirect URIs point to it.
263+
:::
264+
265+
## Present the authentication UI
266+
267+
### Initializing the `MicrosoftSignInService`
268+
269+
Before presenting any sign-in UI, initialize the Microsoft Sign-In service. This step is necessary to configure the service with your Microsoft app credentials.
270+
271+
```dart
272+
await client.auth.initializeMicrosoftSignIn(
273+
clientId: 'YOUR_MICROSOFT_CLIENT_ID',
274+
redirectUri: 'YOUR_REGISTERED_REDIRECT_URI',
275+
);
276+
```
277+
278+
:::info
279+
For more information on configuration options and environment variables, see the [configuration section](./configuration).
280+
:::
281+
282+
### Using the `MicrosoftSignInWidget`
283+
284+
If you have configured the `SignInWidget` as described in the [setup section](../../setup#present-the-authentication-ui), the Microsoft identity provider will be automatically detected and displayed in the sign-in widget.
285+
286+
You can also use the `MicrosoftSignInWidget` to include the Microsoft authentication flow in your own custom UI.
287+
288+
```dart
289+
import 'package:serverpod_auth_idp_flutter/serverpod_auth_idp_flutter.dart';
290+
291+
MicrosoftSignInWidget(
292+
client: client,
293+
onAuthenticated: () {
294+
// Do something when the user is authenticated.
295+
//
296+
// NOTE: You should not navigate to the home screen here, otherwise
297+
// the user will have to sign in again every time they open the app.
298+
},
299+
onError: (error) {
300+
// Handle errors
301+
ScaffoldMessenger.of(context).showSnackBar(
302+
SnackBar(content: Text('Error: $error')),
303+
);
304+
},
305+
)
306+
```
307+
308+
The widget automatically handles:
309+
310+
- Microsoft Sign-In flow for iOS, Android, Web, and macOS.
311+
- OAuth2 authentication flow.
312+
- Token management.
313+
- Underlying OAuth2 package error handling.
314+
315+
For details on how to customize the Microsoft Sign-In UI in your Flutter app, see the [customizing the UI section](./customizing-the-ui).

0 commit comments

Comments
 (0)