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

dev-main 2026-01-17 09:15 UTC

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_access scope

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

  1. Go to Azure Portal
  2. Navigate to Azure Active DirectoryApp registrations
  3. Click New registration
  4. 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
  5. Click Register
  6. Copy the Application (client) ID
  7. Go to Certificates & secretsNew client secret
  8. 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

  1. Visit /backend/auth/signin
  2. Click "Sign in with Microsoft"
  3. Authenticate with your Microsoft account
  4. 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 PortalAzure Active DirectoryOverview

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

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=common or organizations
  • 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.