This project implements a web application chat agent using Azure AI Foundry SDK that retrieves and grounds responses on SharePoint content through Microsoft 365 Copilot Retrieval API. The application provides a web interface for compliance checking and document analysis.
- Web Interface: ASP.NET Core MVC web application with authentication
- Azure AI Foundry Integration: Uses Azure AI SDK for chat completions with configurable models
- SharePoint Content Retrieval: Leverages Microsoft 365 Copilot Retrieval API for content grounding
- Microsoft Identity Integration: OAuth/OpenID Connect authentication with Microsoft 365
- Compliance Checking: Automated policy compliance analysis and violation reporting
- Email Notifications: Send compliance findings to document authors
- .NET 8.0 SDK
- Azure AI Foundry resource
- Microsoft 365 tenant with SharePoint
- Azure App Registration with delegated permissions
git clone <your-repo-url>
cd SPEAgentWithRetrieval-
Create an Azure App Registration:
- Go to Azure Portal
- Navigate to Azure Active Directory → App registrations
- Click New registration
- Name: your app name
- Supported account types: Accounts in this organizational directory only (Single tenant)
- Redirect URI: Web platform with
https://localhost:5001/signin-oidc - Click Register
-
Configure Authentication:
- Go to Authentication in the left menu
- Under Platform configurations:
- Ensure Web platform is configured with redirect URI:
https://localhost:5001/signin-oidc - Add logout URL:
https://localhost:5001/signout-callback-oidc - Enable ID tokens under Implicit grant and hybrid flows
- Ensure Web platform is configured with redirect URI:
- Do NOT enable "Allow public client flows" for web applications
-
Create Client Secret:
- Go to Certificates & secrets
- Click New client secret
- Add description and set expiration
- Copy the secret value immediately (you won't see it again)
-
Configure API Permissions:
- Go to API permissions → Add a permission → Microsoft Graph → Delegated permissions
- Add these permissions:
Files.Read.AllSites.Read.AllMail.SendUser.Read.All
- Click Grant admin consent
-
Copy the example configuration:
cp appsettings.example.json appsettings.json
NB You will need your Azure AI inference endpoint (which is not your Azure AI Foundry Project endpoint). To get this navigate to Models + Endpoints > name of Model Switch the SDK to Azure AI Inference SDK and the code panel should have
some code sample with the relevant endpoint. This endpoint will look something like https://{projectName}.cognitiveservices.azure.com/openai/deployments/{modelName}
-
Update
appsettings.jsonwith your values:{ "AzureAd": { "Instance": "https://login.microsoftonline.com/", "TenantId": "your-tenant-id", "ClientId": "your-client-id", "ClientSecret": "your-client-secret", "CallbackPath": "/signin-oidc", "SignedOutCallbackPath": "/signout-callback-oidc" }, "AzureAIFoundry": { "ProjectEndpoint": "your-azure-ai-inference-endpoint", "ModelName": "your model name", "APIKey": "your-api-key" }, "Microsoft365": { "TenantId": "your-tenant-id", "ClientId": "your-client-id", "FilterExpression": "path:\"https://your-sharepoint-site.sharepoint.com\"" } }
# Install dependencies
dotnet restore
# Build the application
dotnet build
# Run the application
dotnet runThe application will be available at:
- HTTP:
http://localhost:5000 - HTTPS:
https://localhost:5001
- First Run: The application will open a browser for Microsoft 365 authentication
- Subsequent Runs: Tokens are cached, no re-authentication needed
- Compliance Checking: Use the web interface to run compliance checks
- View Results: Responses include source document citations and violation reports
The application is structured around the following components:
- Purpose: Fetches content from SharePoint using Microsoft Graph API.
- Key Component:
CopilotRetrievalService.cs- Retrieves SharePoint content.
- Implements chunking and embedding strategies for retrieval-augmented generation (RAG).
- Handles authentication and API calls using Microsoft Graph SDK.
- Purpose: Generates responses using Azure AI Foundry SDK.
- Key Component:
FoundryService.cs- Synthesizes responses based on retrieved content.
- Implements chat completions and content generation patterns.
- Uses Azure AI SDK for .NET.
- Purpose: Coordinates retrieval and synthesis processes.
- Key Component:
ChatService.cs- Sequentially orchestrates retrieval and synthesis.
- Implements async/await patterns for I/O operations.
- Handles error management and logging.
- Purpose: Displays synthesized responses and sources to the user.
- Key Component:
Program.cs- Manages user input and output.
- Displays top sources and synthesized responses.
- Purpose: Manages application settings and logs.
- Key Components:
appsettings.json: Stores configuration settings.ILogger: Implements structured logging for debugging and monitoring.
- Purpose: Ensures secure access to APIs.
- Key Component: Token caching with
InteractiveBrowserCredential.
+---------------------+
| Presentation |
| Layer |
| (Program.cs) |
+---------------------+
|
v
+---------------------+
| Orchestration |
| Layer |
| (ChatService.cs) |
+---------------------+
|
v
+---------------------+ +---------------------+
| Retrieval Layer | | Synthesis Layer |
| (CopilotRetrieval | | (FoundryService) |
| Service.cs) | | |
+---------------------+ +---------------------+
| |
v v
+---------------------+ +---------------------+
| Microsoft Graph API | | Azure AI Foundry |
| (SharePoint) | | SDK |
+---------------------+ +---------------------+
- No Secrets in Code: All sensitive configuration in
appsettings.json(git-ignored) - Delegated Permissions: Respects user's SharePoint access rights
- Token Security: Uses Azure Identity SDK for secure token handling
Besides the tips below, you can find architectural diagrams in here.
Cause: App registration is configured as SPA instead of Public Client
Solution:
- Go to Azure Portal → App registrations → Your app → Authentication
- Remove all Single-page application platforms
- Keep only Mobile and desktop applications with
http://localhostredirect URI - Ensure Allow public client flows is Enabled
Error: AADSTS7000218 - "The request body must contain the following parameter: 'client_assertion' or 'client_secret'"
Cause: App registration is configured as Confidential Client instead of Public Client
Solution:
- Go to Azure Portal → App registrations → Your app → Authentication
- Set Allow public client flows to Yes
- Use Mobile and desktop applications platform (not Web or SPA)
- Verify app registration has "Allow public client flows" enabled
- Ensure delegated permissions are granted with admin consent
- Check that redirect URI
http://localhostis configured - Remove any SPA or Web platform configurations that might conflict
- Verify the user has access to the SharePoint content
- Check the
FilterExpressionpath is correct - Ensure
Sites.Read.AllandFiles.ReadWrite.Allpermissions are granted
NB You will need your Azure AI inference endpoint (which is not your Azure AI Foundry Project endpoint). To get this navigate to Models + Endpoints > name of Model Switch the SDK to Azure AI Inference SDK and the code panel should have
some code sample with the relevant endpoint. This endpoint will look something like https://{projectName}.cognitiveservices.azure.com/openai/deployments/{modelName}
- Ensure you have the right endpoint url (see above)
- Ensure the model name matches your deployment
- Check Azure AI Foundry resource permissions
For convenience, this repository includes automation scripts to fix common Azure AD app registration issues:
./fix-azure-app-registration.sh./fix-azure-app-registration.ps1These scripts will automatically:
- Remove SPA platform configurations
- Add Mobile/Desktop platform with correct redirect URI
- Enable public client flows
- Display current configuration for verification
- Fork the repository
- Create a feature branch
- Make your changes
- Ensure
appsettings.jsonis not committed - Submit a pull request
This project is licensed under the MIT License.