winter / wn-ssoprovidermicrosoft-plugin
Microsoft 365 and Azure AD authentication provider for Winter.SSO
Fund package maintenance!
wintercms
Open Collective
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Type:winter-plugin
pkg:composer/winter/wn-ssoprovidermicrosoft-plugin
Requires
- socialiteproviders/microsoft: ^4.3
- winter/wn-sso-plugin: dev-main
This package is not auto-updated.
Last update: 2026-01-18 07:34:15 UTC
README
Microsoft 365 and Azure AD authentication provider for Winter.SSO.
Allow your backend users to sign in using their Microsoft accounts, including:
- Microsoft 365 (formerly Office 365) work or school accounts
- Azure Active Directory (Azure AD / Entra ID) accounts
- Personal Microsoft accounts (@outlook.com, @live.com, @hotmail.com)
Features
- Multi-tenant support: Allow users from any Microsoft 365 organization
- Single-tenant support: Restrict to your specific Azure AD tenant
- Flexible account types: Work/school accounts, personal accounts, or both
- Tenant information: Optionally retrieve tenant details for verification
- User roles/groups: Access Microsoft 365 group memberships via
.getRoles() - Profile photos: Automatically fetch user avatars
- Refresh tokens: Support for
offline_accessscope
Installation
composer require winter/wn-ssoprovidermicrosoft-plugin
Requirements
- Winter CMS v1.2+
- PHP 8.0.2+
- Winter.SSO plugin
- Azure AD application (or Microsoft 365 tenant)
Quick Start
1. Create Azure AD Application
- Go to Azure Portal
- Navigate to Azure Active Directory → App registrations
- Click New registration
- Configure:
- Name: Your Application Name
- Supported account types:
- Multi-tenant (public): "Accounts in any organizational directory and personal Microsoft accounts"
- Single-tenant (private): "Accounts in this organizational directory only"
- Redirect URI:
https://example.com/backend/winter/sso/handle/callback/microsoft
- Click Register
- Copy the Application (client) ID
- Go to Certificates & secrets → New client secret
- Create and copy the secret Value (not the Secret ID)
See Detailed Setup Guide for screenshots and step-by-step instructions.
2. Configure Environment
Add to your .env file:
MICROSOFT_CLIENT_ID=your_application_client_id MICROSOFT_CLIENT_SECRET=your_client_secret_value # Tenant configuration (default: 'common') # 'common' = any Microsoft account (multi-tenant) # 'organizations' = work/school accounts only # 'consumers' = personal Microsoft accounts only # Or use your specific tenant ID for single-tenant MICROSOFT_TENANT=common
3. Enable Provider
Create or edit config/winter/sso/config.php:
<?php return [ 'enabled_providers' => [ 'microsoft', ], ];
4. Test
- Visit
/backend/auth/signin - Click "Sign in with Microsoft"
- Authenticate with your Microsoft account
- You should be logged in to the Winter CMS backend!
Configuration Options
Multi-tenant (Public) Setup
Allow users from any Microsoft 365 organization:
MICROSOFT_TENANT=common
Or work/school accounts only (no personal accounts):
MICROSOFT_TENANT=organizations
Single-tenant (Private) Setup
Restrict to your specific Azure AD tenant:
MICROSOFT_TENANT=12345678-1234-1234-1234-123456789012
Get your tenant ID from: Azure Portal → Azure Active Directory → Overview
Optional Features
Include tenant information:
MICROSOFT_INCLUDE_TENANT_INFO=true
Include user profile photo:
MICROSOFT_INCLUDE_AVATAR=true
Request additional scopes (comma-separated):
MICROSOFT_SCOPES=offline_access,User.Read
See config/config.php for all available options.
Advanced Usage
Restricting to Specific Tenants
You can use events to restrict which tenants are allowed:
// In a plugin or theme's boot() method Event::listen('winter.sso.microsoft.authenticated', function ($ssoUser) { $allowedTenants = ['tenant-id-1', 'tenant-id-2']; if (!in_array($ssoUser->tenant['id'], $allowedTenants)) { throw new AuthenticationException('Tenant not allowed'); } });
Accessing Group Memberships
Event::listen('winter.sso.microsoft.afterLogin', function ($user, $ssoUser) { // Get Microsoft 365 groups the user belongs to $groups = $ssoUser->getRoles(); // Returns array of group names // Assign Winter CMS role based on Microsoft group if (in_array('Admins', $groups)) { $user->role = 'developer'; $user->save(); } });
Populating User Details
Event::listen('winter.sso.microsoft.registered', function ($user, $ssoUser) { $user->fill([ 'first_name' => $ssoUser->user['givenName'] ?? null, 'last_name' => $ssoUser->user['surname'] ?? null, ]); $user->save(); });
Documentation
- Detailed Setup Guide - Step-by-step Azure AD configuration with screenshots
- Winter.SSO Documentation - Core SSO plugin docs
- Microsoft Identity Platform - Official Microsoft OAuth documentation
- SocialiteProviders Microsoft - Socialite provider documentation
Redirect URL
Your Azure AD application must be configured with this exact redirect URI:
https://example.com/backend/winter/sso/handle/callback/microsoft
Replace https://example.com with your actual domain. The path must be exactly as shown.
Troubleshooting
"AADSTS50011: The redirect URI specified in the request does not match"
Cause: Redirect URI in Azure AD doesn't match exactly.
Solution:
- Go to Azure Portal → App registrations → Your app → Authentication
- Ensure redirect URI is:
https://example.com/backend/winter/sso/handle/callback/microsoft - Must match exactly (including https/http, trailing slashes, etc.)
"AADSTS700016: Application not found in the directory"
Cause: Using tenant-specific endpoint with multi-tenant app, or vice versa.
Solution:
- Multi-tenant: Use
MICROSOFT_TENANT=commonororganizations - Single-tenant: Use
MICROSOFT_TENANT=your-tenant-id - Ensure "Supported account types" in Azure AD matches your configuration
"AADSTS50105: The signed in user is not assigned to a role for the application"
Cause: Azure AD is configured to require user assignment, but user not assigned.
Solution:
- Azure Portal → Enterprise applications → Your app → Users and groups
- Either assign users, or go to Properties and set "User assignment required?" to "No"
"The provider microsoft is not enabled"
Cause: Provider not in enabled_providers array in Winter.SSO config.
Solution: Add 'microsoft' to config/winter/sso/config.php:
'enabled_providers' => ['microsoft'],
Additional Help
See Winter.SSO Troubleshooting for general SSO issues.
Alternative: Microsoft Azure Provider
For Azure-specific features like logout URLs, consider using the Microsoft-Azure Socialite provider instead. This would require creating a separate Winter.SSOProviderMicrosoftAzure plugin.
The Microsoft provider (this plugin) is recommended for most use cases.