Skip to content
Petkir Blog
XLinkedinBluesky

Why the On‑Behalf‑Of (OBO) Flow Matters

Code, Azure, SharePoint, SPFx7 min read

Taming Duplicate Content in SharePoint

If you’ve ever managed a busy SharePoint document library, you know the pain: "Final.docx", "Final_Draft.docx", "Final_ReallyThisTime.docx", "Veraft.doc", "Finanal.doc", "Final_ord.doc", "finel.doc", "Dravt.doc"—and so on. Duplicates and outdated drafts pile up, cluttering your workspace, confusing users, and turning compliance into a chore.

The real problem for users is knowing which version is truly the right one. When you search, you might get five nearly identical results—leaving you to guess which is correct, or worse, accidentally pick the wrong one.

Even tools like Copilot can struggle: sometimes it finds multiple documents on the same topic, but with a slightly different question, it might only show one. From an information perspective, this inconsistency makes it hard for users to trust which version Copilot is referencing—especially if only one reference is shown. As long as there are multiple similar files, it’s difficult for users to be confident they’re working with the right document.

Out-of-the-Box Options: The Good, the Bad, and the Messy

SharePoint offers several built-in strategies to help manage document chaos:

  • Delete duplicates manually — a tedious and error-prone process that doesn’t scale well.
  • Rely on SharePoint versioning — useful for maintaining history, but users often bypass it by creating new files instead of new versions.
  • Organize with separate sites or libraries — restrict access to drafts through permissions and keep draft libraries out of search results.
  • Automate cleanup using Copilot or Power Automate — these tools can help, but require careful setup and ongoing governance.

These approaches can work, but they often leave users anxious about losing important drafts—or unsure where the “real” final version lives.

A Safer Approach: Archive to Azure Blob Storage

Sometimes the best way to give users peace of mind is not to delete files outright, but to archive them somewhere safe. Enter the Move Docs 2 Blob solution—a sample that moves outdated or duplicate documents from SharePoint to Azure Blob Storage. Your libraries stay clean, while files remain accessible if needed.

This approach offers the best of both worlds:

  • Clean SharePoint libraries for active collaboration.
  • Low-cost, long‑term storage for old versions and drafts.
  • User trust — nothing is lost, just moved.

How the “Move Docs 2 Blob” Sample Works

The sample react-command-movedoc2blob is built with the SharePoint Framework (SPFx), Azure Functions, and Azure Blob Storage. The magic lies in secure, delegated authentication using the On‑Behalf‑Of (OBO) flow.

Why the OBO Flow?

When a user triggers the archive command in SharePoint, the solution must access both SharePoint and Azure resources as that user—not as a background app. This ensures actions are auditable and respect user permissions.

The OBO flow lets the backend (an Azure Function) exchange the user’s SharePoint token for a new token that can access Azure resources—without exposing credentials or requiring extra logins.

Understanding the On‑Behalf‑Of (OBO) Token Flow

The OBO authentication flow is a Microsoft identity pattern that enables your backend service (like an Azure Function) to securely act on behalf of a user. This is crucial when your solution needs to access resources (such as SharePoint or Microsoft Graph) using the user’s own permissions—not just app‑level permissions.

What Do Delegated Permissions Mean?

With delegated permissions, your backend receives a token that represents the user—not just the application. This means:

  • All actions are performed as the user.
  • Audit logs and compliance records reflect the actual user’s identity.
  • Access is limited to what the user can do—the app cannot overstep the user’s rights.

Let me try to explain in another way: with delegated permissions, your backend service is never acting alone or with unrestricted power. Instead, it’s as if the user themselves is performing the action, but through your app. The app can only do what the user could do if they were interacting directly—no more, no less. This maintains security boundaries and preserves user trust.

Why This Matters

  • Security — the app cannot be used to gain access to resources a user shouldn’t see.
  • Compliance — all actions are traceable to the real user.
  • User trust — permissions are respected throughout.

Where the Token Exchange Happens

Look for the C# code in the Azure Functions backend—specifically in TokenService.cs. There, the incoming user token is exchanged for a new token with the required scopes to access Blob Storage, using Microsoft.Identity.Client (MSAL) and the OBO flow.

Key Implementation Pieces

  • SPFx extension — a custom command set (React) triggers the archive action from the SharePoint UI.
  • Azure Functions backend — receives the request, validates the user, and moves the document.
  • Token exchange — SPFx sends the user’s access token; the function performs OBO with MSAL.
  • Blob Storage integration — uploads the document using the Azure.Storage.Blobs SDK.
  • Audit and metadata — write trace data to Azure Table Storage for compliance.
  • SharePoint cleanup — after successful archiving, delete or flag the original as archived.
  • Audit trail — every move is logged so you know what was archived, when, and by whom.

End‑to‑End Flow

  1. User selects documents to archive in SharePoint.
  2. The SPFx extension calls the Azure Function, passing the user’s token.
  3. The function validates the user and moves the document to Blob Storage.
  4. Audit records are created for compliance.
  5. The SharePoint library is cleaned up—but nothing is lost.

Registering Your Azure AD (Entra ID) App for SharePoint API Access

To enable secure, delegated access to SharePoint from your backend (such as an Azure Function), you must register an application in Entra ID (formerly Azure AD) and configure it with the correct permissions and scopes. This registration is the foundation for enabling the On‑Behalf‑Of (OBO) flow, ensuring your solution can act as the user—never overstepping their rights.

Register a New Application in Entra ID

  1. Navigate to the Azure Portal and open the Entra ID (Azure Active Directory) blade.
  2. Go to App registrations and click New registration.
  3. Give your app a meaningful name, such as Move Documents2Blob App.
  4. Set the supported account types (usually "Accounts in this organizational directory only").

Configure API Permissions for SharePoint

Your app needs delegated permissions to access SharePoint on behalf of the user. This is crucial for the OBO flow.

  • Go to API permissions > Add a permission > SharePoint.
  • Select Delegated permissions.
  • Add the following permissions:
    • AllSites.Read — allows reading all site collections the signed-in user can access.
    • AllSites.Write — allows reading and writing to all site collections the user can access.

Note: These permissions do not grant your app unrestricted access. With delegated permissions, the app can only access what the signed-in user can access. This is a key security feature of the OBO flow.

App Registration Permissions

Define a Custom Scope for Delegation

To enable your SPFx extension to obtain tokens for your Azure Function, define a custom scope (an "exposed API" for delegated access) in your app registration.

  • In your app registration, go to Expose an API.
  • Click Add a scope.
  • Set the scope name, for example: access_as_user.
  • Provide a user consent display name and description (e.g., "Access Move Documents2Blob API as the signed-in user").
  • Set the scope to be enabled.

This custom scope is what your SPFx extension will request when calling your Azure Function, and it is required for the OBO flow to work seamlessly.

App Registration Scope

Grant Admin Consent

Some permissions, such as AllSites.Write, require admin consent. In the API permissions tab, click Grant admin consent for your tenant to approve these permissions.

Configuring API Permissions in SPFx

To enable the SPFx extension to call your Azure Function on behalf of the user, you need to configure API permissions in your solution's package-solution.json file. This is done using the webApiPermissionRequests property, which requests delegated permissions for your registered Azure AD (Entra ID) app.

Example configuration:

"webApiPermissionRequests": [
{
"resource": "Move Documents2Blob App",
"scope": "access_as_user",
"appId": "yourID",
"replyUrl": "http://localhost:7158"
}

Conclusion

Managing duplicate and outdated documents in SharePoint doesn’t have to mean deleting files and risking user trust. By archiving to Azure Blob Storage with delegated OBO authentication, you keep libraries clean, users happy, and compliance teams satisfied.

The react-command-movedoc2blob sample shows how to implement this pattern with modern Microsoft 365 and Azure technologies. Explore the code, adapt it to your needs, and give users confidence that their work is safe—even as you tidy up the digital workspace.