Customer Portal: Secure External Access with Azure B2C, Power Pages, and SharePoint
Introduction
[Explain business need: enable partners/customers to access resources securely without internal AD accounts; integrated experience across identity, portal UX, and content repositories.]
Solution Architecture
Components Overview
| Component | Role | Key Features |
|---|---|---|
| Azure AD B2C | External identity provider | Social logins, MFA, custom policies |
| Power Pages | Portal framework | Low-code, responsive, integrated auth |
| Dataverse | Customer data store | Tables, business rules, security roles |
| SharePoint | Document repository | External sharing, versioning, DLP |
| Power Automate | Workflow automation | Approvals, notifications, integrations |
Step-by-Step Guide
Step 1: Configure Azure AD B2C Tenant
# Create B2C tenant (via Azure Portal)
# Tenant name: contosocustomers.onmicrosoft.com
# Register Power Pages app
az ad app create --display-name "Customer Portal" --sign-in-audience AzureADandPersonalMicrosoftAccount
User Flows:
- Sign-up and sign-in (email verification)
- Password reset (self-service)
- Profile editing
Custom Attributes:
- Company Name
- Customer Tier (Bronze, Silver, Gold)
- Account Manager
Step 2: Create Power Pages Site
Via Power Platform Admin Center:
- Create new Power Pages site
- Select template: "Partner Portal"
- Configure authentication: Azure AD B2C
- Authority:
https://contosocustomers.b2clogin.com/contosocustomers.onmicrosoft.com/B2C_1_SignUpSignIn - Client ID: from B2C app registration
- Authority:
Step 3: Design Portal Pages
Home Page:
<div class="hero-section">
<h1>Welcome, {{ user.fullname }}</h1>
<p>Your account tier: <strong>{{ user.customertier }}</strong></p>
</div>
<div class="quick-links">
<a href="/resources">Document Library</a>
<a href="/support">Submit Support Ticket</a>
<a href="/profile">My Profile</a>
</div>
Document Library (Dataverse Integration):
{% entitylist id:'customer-documents' %}
{% endentitylist %}
Step 4: Dataverse Security Model
Tables:
- Customer Account (extends Contact)
- Support Ticket
- Shared Document Metadata
Web Roles:
- Customer User (read own records)
- Premium Customer (read + create tickets)
- Guest (browse public resources only)
Table Permissions:
Table: Support Ticket
Web Role: Customer User
Privileges: Create (own), Read (own), Write (own)
Scope: Contact (relationship to authenticated user)
Step 5: SharePoint Integration
Enable External Sharing:
Set-SPOSite -Identity https://contoso.sharepoint.com/sites/customerportal -SharingCapability ExternalUserAndGuestSharing
Embed Document Library in Portal:
<iframe src="https://contoso.sharepoint.com/sites/customerportal/_layouts/15/embed.aspx?List={listid}&View={viewid}" width="100%" height="600"></iframe>
Or via Power Automate:
Trigger: When file is added (SharePoint)
Action: Create record in Dataverse (Shared Document Metadata)
- Title: File Name
- URL: File Link
- Shared With: Portal User
Step 6: Support Ticket Workflow
Power Automate Flow:
- Trigger: When a row is added (Dataverse - Support Ticket)
- Condition: If Severity = "High"
- Yes: Create Planner task for support team
- No: Send email to support queue
- Action: Update ticket status to "In Progress"
- Action: Notify customer via portal notification
Step 7: Document Approval Workflow
Trigger: When file is added to "Pending Approval" folder (SharePoint)
Action: Start approval process
- Approvers: Account Manager (from B2C custom attribute)
Condition: If Approved
- Action: Move file to "Approved Documents" library
- Action: Grant access to customer via external sharing link
- Action: Send notification to customer portal
Step 8: Multi-Factor Authentication
B2C Custom Policy (XML):
<TechnicalProfile Id="AAD-UserReadUsingObjectId">
<Metadata>
<Item Key="IncludeClaimResolvingInClaimsHandling">true</Item>
</Metadata>
<OutputClaims>
<OutputClaim ClaimTypeReferenceId="strongAuthenticationPhoneNumber" />
</OutputClaims>
</TechnicalProfile>
MFA Enforcement:
<OrchestrationStep Order="3" Type="ClaimsExchange">
<ClaimsExchanges>
<ClaimsExchange Id="PhoneVerification" TechnicalProfileReferenceId="PhoneFactor-InputOrVerify" />
</ClaimsExchanges>
</OrchestrationStep>
Advanced Features
Custom Branding
B2C Page Customization:
<!-- custom.html hosted in Azure Storage -->
<!DOCTYPE html>
<html>
<head>
<title>Contoso Customer Login</title>
<link rel="stylesheet" href="custom.css">
</head>
<body>
<div id="api"></div> <!-- B2C injects auth UI here -->
</body>
</html>
Analytics & Monitoring
Application Insights Integration:
// Power Pages tracking code
appInsights.trackPageView({ name: 'DocumentLibrary', properties: { userTier: '{{ user.customertier }}' } });
B2C Audit Logs:
AuditLogs
| where OperationName == "Sign-in activity"
| extend UserPrincipalName = tostring(TargetResources[0].userPrincipalName)
| summarize LoginCount = count() by UserPrincipalName
| order by LoginCount desc
Self-Service Profile Management
Power Pages Form:
{% editable snippets 'profile-form' type: 'html' %}
<form method="post" action="/profile/update">
<input name="fullname" value="{{ user.fullname }}" />
<input name="email" value="{{ user.email }}" readonly />
<input name="companyname" value="{{ user.companyname }}" />
<button type="submit">Update Profile</button>
</form>
{% endeditable %}
Security & Compliance
Data Loss Prevention
New-DlpCompliancePolicy -Name "Customer Portal Policy" -SharePointLocation "https://contoso.sharepoint.com/sites/customerportal"
New-DlpComplianceRule -Name "PII Protection" -Policy "Customer Portal Policy" -ContentContainsSensitiveInformation @{Name="Credit Card Number"} -BlockAccess $true
Conditional Access
B2C Conditional Access (via Azure AD Premium P2):
- Require MFA for high-risk sign-ins
- Block access from untrusted locations
- Require compliant device for sensitive documents
Audit & Compliance Reporting
# Export B2C sign-in logs
Get-AzureADAuditSignInLogs -Filter "appId eq 'app-id'" | Export-Csv -Path "b2c-logins.csv"
# SharePoint access reports
Get-SPOSiteGroup -Site https://contoso.sharepoint.com/sites/customerportal | Select-Object Title, Users
Performance Optimization
- Enable CDN for Power Pages static assets
- Use SharePoint CDN for document thumbnails
- Cache Dataverse queries with OutputCache in portal code
- Optimize B2C token size (minimal claims)
Cost Management
| Service | Cost Driver | Optimization |
|---|---|---|
| Azure AD B2C | MAU (Monthly Active Users) | Use free tier (50K MAU) |
| Power Pages | Anonymous/authenticated users | Monitor user count |
| SharePoint | Storage + API calls | Archive inactive docs |
| Power Automate | Flow runs | Consolidate triggers |
Troubleshooting
Issue: Users can't sign in
Solution: Verify B2C app registration redirect URIs; check user flow assignment
Issue: SharePoint documents not visible
Solution: Verify external sharing settings; check permission inheritance
Issue: Portal performance slow
Solution: Enable Output Cache; review liquid template complexity
Best Practices
- Use B2C custom policies for advanced scenarios
- Implement tiered access (Bronze/Silver/Gold)
- Automate user provisioning via Graph API
- Monitor portal usage analytics
- Test external user experience regularly
Key Takeaways
- Azure AD B2C provides enterprise-grade external identity.
- Power Pages accelerates portal development with low-code.
- SharePoint enables secure document collaboration.
- Dataverse centralizes customer data with robust security.
- Power Automate orchestrates approval and notification workflows.
Next Steps
- Implement multi-language support for global customers
- Add AI Builder for document processing
- Build mobile app experience via Power Apps
Additional Resources
How will you transform your customer experience?