|
| 1 | +# Agent Instructions: Create iOS/macOS Sample Application with Microsoft Entra ID - Workforce configuration |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +These instructions guide agents through creating a sample iOS or macOS application that implements user sign-in using Microsoft Entra ID (formerly Azure AD) and calls the Microsoft Graph API. |
| 6 | + |
| 7 | +## Prerequisites |
| 8 | + |
| 9 | +Before starting, ensure the following requirements are met: |
| 10 | + |
| 11 | +### Azure Requirements |
| 12 | + |
| 13 | +- Active Azure subscription with an active account |
| 14 | +- Permissions to manage applications (requires one of these roles): |
| 15 | + - Application Administrator |
| 16 | + - Application Developer |
| 17 | +- A workforce tenant (or create a new tenant) |
| 18 | + |
| 19 | +### Development Environment |
| 20 | + |
| 21 | +- **iOS**: Version 16 or higher (for iOS apps) |
| 22 | +- **macOS**: Version 11 or higher (for macOS apps) |
| 23 | +- **CocoaPods**: For dependency management |
| 24 | + |
| 25 | +### Pre-Configuration |
| 26 | + |
| 27 | +- Register a new application in the Microsoft Entra admin center |
| 28 | +- Configure for "Accounts in this organizational directory only" |
| 29 | +- Record the following values from the application Overview page: |
| 30 | + - **Application (client) ID** |
| 31 | + - **Directory (tenant) ID** |
| 32 | + |
| 33 | +## Step 1: Register Application in Microsoft Entra Admin Center |
| 34 | + |
| 35 | +### 1.1 Create App Registration |
| 36 | + |
| 37 | +1. Navigate to the [Microsoft Entra admin center](https://entra.microsoft.com) |
| 38 | +2. Select **Applications** > **App registrations** > **New registration** |
| 39 | +3. Enter a name for your application |
| 40 | +4. Select "Accounts in this organizational directory only" as the supported account types |
| 41 | +5. Click **Register** |
| 42 | +6. Save the **Application (client) ID** and **Directory (tenant) ID** from the Overview page |
| 43 | + |
| 44 | +### 1.2 Configure Platform (iOS/macOS) |
| 45 | + |
| 46 | +1. Under **Manage**, select **Authentication** > **Add Platform** > **iOS/macOS** |
| 47 | +2. Enter your **Bundle Identifier** (e.g., `com.<yourname>.identitysample.MSALMacOS`) |
| 48 | + - Note: This is a unique string that identifies your application |
| 49 | + - The iOS configuration also applies to macOS applications |
| 50 | +3. Click **Configure** and save the **MSAL Configuration** details |
| 51 | +4. Click **Done** |
| 52 | + |
| 53 | +### 1.3 Enable Public Client Flow |
| 54 | + |
| 55 | +1. Under **Manage**, select **Authentication** |
| 56 | +2. Scroll to **Advanced settings** |
| 57 | +3. For **Allow public client flows**, select **Yes** |
| 58 | +4. Click **Save** |
| 59 | + |
| 60 | +## Step 2: Download Sample Code |
| 61 | + |
| 62 | +### 2.1 Download the Project |
| 63 | + |
| 64 | +Choose the appropriate sample based on your target platform: |
| 65 | + |
| 66 | +**For iOS:** |
| 67 | + |
| 68 | +```bash |
| 69 | +curl -L https://github.com/Azure-Samples/active-directory-ios-swift-native-v2/archive/master.zip -o ios-sample.zip |
| 70 | +unzip ios-sample.zip |
| 71 | +cd active-directory-ios-swift-native-v2-master |
| 72 | +``` |
| 73 | + |
| 74 | +**For macOS:** |
| 75 | + |
| 76 | +```bash |
| 77 | +curl -L https://github.com/Azure-Samples/active-directory-macOS-swift-native-v2/archive/master.zip -o macos-sample.zip |
| 78 | +unzip macos-sample.zip |
| 79 | +cd active-directory-macOS-swift-native-v2-master |
| 80 | +``` |
| 81 | + |
| 82 | +## Step 3: Install Dependencies |
| 83 | + |
| 84 | +### 3.1 Install MSAL Library |
| 85 | + |
| 86 | +1. Open Terminal and navigate to the project directory |
| 87 | +2. Run CocoaPods to install the Microsoft Authentication Library (MSAL): |
| 88 | +```bash |
| 89 | +pod install |
| 90 | +``` |
| 91 | +3. Wait for the installation to complete |
| 92 | + |
| 93 | +### 3.2 Open Workspace |
| 94 | + |
| 95 | +After pod installation, open the `.xcworkspace` file (NOT the `.xcodeproj` file): |
| 96 | + |
| 97 | +```bash |
| 98 | +open *.xcworkspace |
| 99 | +``` |
| 100 | + |
| 101 | +## Step 4: Configure the Application |
| 102 | + |
| 103 | +### 4.1 Update ViewController.swift |
| 104 | + |
| 105 | +1. In Xcode, open the project navigator |
| 106 | +2. Locate and open **ViewController.swift** |
| 107 | +3. Find the line starting with `let kClientID` and replace it with your Application (client) ID: |
| 108 | + |
| 109 | +```swift |
| 110 | +let kClientID = "YOUR_APPLICATION_CLIENT_ID_HERE" |
| 111 | +``` |
| 112 | + |
| 113 | +### 4.2 Configure Endpoints |
| 114 | + |
| 115 | +For standard Microsoft Entra ID (global access), use default values: |
| 116 | + |
| 117 | +```swift |
| 118 | +let kGraphEndpoint = "https://graph.microsoft.com/" |
| 119 | +let kAuthority = "https://login.microsoftonline.com/common" |
| 120 | +``` |
| 121 | + |
| 122 | +**For national clouds** (if applicable): |
| 123 | + |
| 124 | +- **Microsoft Entra Germany:** |
| 125 | + |
| 126 | +```swift |
| 127 | +let kGraphEndpoint = "https://graph.microsoft.de/" |
| 128 | +let kAuthority = "https://login.microsoftonline.de/common" |
| 129 | +``` |
| 130 | + |
| 131 | +See [Microsoft Graph deployments documentation](https://learn.microsoft.com/en-us/graph/deployments#app-registration-and-token-service-root-endpoints) for other endpoints. |
| 132 | + |
| 133 | +### 4.3 Configure Bundle Identifier |
| 134 | + |
| 135 | +1. In Xcode, select the project in the navigator |
| 136 | +2. Select your target |
| 137 | +3. Go to the **General** tab |
| 138 | +4. In the **Identity** section, set the **Bundle Identifier** to match what you registered in the Azure portal |
| 139 | + |
| 140 | +### 4.4 Update Info.plist |
| 141 | + |
| 142 | +1. Right-click **Info.plist** in the project navigator |
| 143 | +2. Select **Open As** > **Source Code** |
| 144 | +3. Find the `CFBundleURLTypes` section under the dict root node |
| 145 | +4. Replace `Enter_the_Bundle_Id_Here` with your Bundle Identifier |
| 146 | +5. Note: Keep the `msauth.` prefix in the string |
| 147 | + |
| 148 | +```xml |
| 149 | +<key>CFBundleURLTypes</key> |
| 150 | +<array> |
| 151 | + <dict> |
| 152 | + <key>CFBundleURLSchemes</key> |
| 153 | + <array> |
| 154 | + <string>msauth.YOUR_BUNDLE_IDENTIFIER_HERE</string> |
| 155 | + </array> |
| 156 | + </dict> |
| 157 | +</array> |
| 158 | +``` |
| 159 | + |
| 160 | +## Step 5: Build and Run the Application |
| 161 | + |
| 162 | +### 5.1 Build the Project |
| 163 | + |
| 164 | +1. Select your target device or simulator from the scheme selector |
| 165 | +2. Click the **Build** button (⌘+B) or select **Product** > **Build** |
| 166 | +3. Verify there are no build errors |
| 167 | + |
| 168 | +### 5.2 Run the Application |
| 169 | + |
| 170 | +1. Select **Product** > **Run** from the menu (or press ⌘+R) |
| 171 | +2. The app will launch in the simulator or on your connected device |
| 172 | + |
| 173 | +### 5.3 Test Authentication |
| 174 | + |
| 175 | +1. When the app launches, you'll see the main interface |
| 176 | +2. Click **Sign In** or **Acquire Token Interactively** |
| 177 | +3. You'll be prompted to enter your credentials |
| 178 | +4. After successful authentication, the app will display user information |
| 179 | +5. The app can now make authenticated calls to Microsoft Graph API |
| 180 | + |
| 181 | +## Step 6: Understanding the Code Flow |
| 182 | + |
| 183 | +### Authentication Flow Diagram |
| 184 | + |
| 185 | +``` |
| 186 | +User clicks "Sign In" |
| 187 | + ↓ |
| 188 | +App initiates MSAL authentication |
| 189 | + ↓ |
| 190 | +Browser/Web view opens with Microsoft login |
| 191 | + ↓ |
| 192 | +User enters credentials |
| 193 | + ↓ |
| 194 | +Microsoft Entra ID validates credentials |
| 195 | + ↓ |
| 196 | +Redirect back to app with authorization code |
| 197 | + ↓ |
| 198 | +MSAL exchanges code for access token |
| 199 | + ↓ |
| 200 | +App receives access token |
| 201 | + ↓ |
| 202 | +App can call Microsoft Graph API |
| 203 | +``` |
| 204 | + |
| 205 | +### Key Components |
| 206 | + |
| 207 | +- **MSAL Library**: Handles authentication and token management |
| 208 | +- **ViewController**: Main UI and authentication logic |
| 209 | +- **Microsoft Graph API**: Provides access to user data and resources |
| 210 | +- **Access Token**: JWT token used to authenticate API calls |
| 211 | + |
| 212 | +## Step 7: Testing the Application |
| 213 | + |
| 214 | +### 7.1 Interactive Sign-In |
| 215 | + |
| 216 | +Test the interactive authentication flow: |
| 217 | + |
| 218 | +1. Launch the app |
| 219 | +2. Click **Acquire Token Interactively** |
| 220 | +3. Enter valid test credentials |
| 221 | +4. Verify successful sign-in |
| 222 | +5. Check that user information is displayed |
| 223 | + |
| 224 | +### 7.2 Silent Token Acquisition |
| 225 | + |
| 226 | +Test silent token refresh: |
| 227 | + |
| 228 | +1. After initial sign-in, click **Acquire Token Silently** |
| 229 | +2. Verify token is obtained without user interaction |
| 230 | +3. This uses cached refresh tokens |
| 231 | + |
| 232 | +### 7.3 Microsoft Graph API Call |
| 233 | + |
| 234 | +Test API access: |
| 235 | + |
| 236 | +1. Click **Get Graph Data Interactively** or **Get Graph Data Silently** |
| 237 | +2. Verify the app successfully calls Microsoft Graph API |
| 238 | +3. Check that user profile data is displayed |
| 239 | + |
| 240 | +## Step 8: Common Configuration Issues |
| 241 | + |
| 242 | +### Issue: "Redirect URI mismatch" |
| 243 | + |
| 244 | +- **Solution**: Verify Bundle Identifier in Info.plist matches Azure portal configuration |
| 245 | +- Ensure `msauth.` prefix is included in the redirect URI |
| 246 | + |
| 247 | +### Issue: "Invalid client" |
| 248 | + |
| 249 | +- **Solution**: Double-check Application (client) ID in ViewController.swift |
| 250 | +- Ensure no extra spaces or characters |
| 251 | + |
| 252 | +### Issue: "Pod install fails" |
| 253 | + |
| 254 | +- **Solution**: Update CocoaPods: `sudo gem install cocoapods` |
| 255 | +- Clear pod cache: `pod cache clean --all` |
| 256 | +- Try again: `pod install` |
| 257 | + |
| 258 | +### Issue: "Build fails with MSAL errors" |
| 259 | + |
| 260 | +- **Solution**: Ensure you opened the `.xcworkspace` file, not `.xcodeproj` |
| 261 | +- Clean build folder: **Product** > **Clean Build Folder** (⇧⌘K) |
| 262 | + |
| 263 | +## Step 9: Next Steps |
| 264 | + |
| 265 | +After successfully building and running the sample: |
| 266 | + |
| 267 | +### For iOS Applications |
| 268 | + |
| 269 | +- Follow the tutorial: [Sign in users and call Microsoft Graph from an iOS app](https://learn.microsoft.com/en-us/entra/identity-platform/tutorial-v2-ios) |
| 270 | +- Implement additional Microsoft Graph API calls |
| 271 | +- Add custom UI and branding |
| 272 | +- Implement token caching strategies |
| 273 | + |
| 274 | +### For macOS Applications |
| 275 | + |
| 276 | +- Follow the iOS tutorial (also applies to macOS): [Sign in users and call Microsoft Graph from a iOS/macOS app](https://learn.microsoft.com/en-us/entra/identity-platform/tutorial-v2-ios) |
| 277 | +- Implement additional application features |
| 278 | +- Add keychain integration for secure token storage |
| 279 | + |
| 280 | +### General Enhancements |
| 281 | + |
| 282 | +- Implement error handling and retry logic |
| 283 | +- Add logging and telemetry |
| 284 | +- Configure additional API scopes |
| 285 | +- Implement sign-out functionality |
| 286 | +- Add multi-account support |
| 287 | + |
| 288 | +## Additional Resources |
| 289 | + |
| 290 | +- **MSAL Documentation**: [Microsoft Authentication Library for iOS and macOS](https://github.com/AzureAD/microsoft-authentication-library-for-objc) |
| 291 | +- **Microsoft Graph API**: [Microsoft Graph REST API reference](https://learn.microsoft.com/en-us/graph/api/overview) |
| 292 | +- **Authentication Flows**: [OAuth 2.0 and OpenID Connect protocols](https://learn.microsoft.com/en-us/entra/identity-platform/v2-protocols) |
| 293 | +- **Best Practices**: [Security best practices for application developers](https://learn.microsoft.com/en-us/entra/identity-platform/identity-platform-integration-checklist) |
| 294 | + |
| 295 | +## Security Considerations |
| 296 | + |
| 297 | +1. **Never hardcode secrets**: Use secure storage mechanisms |
| 298 | +2. **Validate tokens**: Always validate tokens server-side for API calls |
| 299 | +3. **Use HTTPS**: Ensure all network communication uses HTTPS |
| 300 | +4. **Minimal scopes**: Request only the minimum required API scopes |
| 301 | +5. **Token expiration**: Handle token expiration and refresh appropriately |
| 302 | +6. **Secure storage**: Use iOS Keychain or macOS Keychain for sensitive data |
| 303 | + |
| 304 | +--- |
| 305 | + |
| 306 | +**Source**: [Microsoft Learn - Quickstart: Sign in users in a sample mobile app](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-mobile-app-sign-in) |
0 commit comments