Search by

winter / wn-ssoprovidermicrosoft-plugin

LukeTowers

Microsoft 365 and Azure AD authentication provider for Winter.SSO

Package info

github.com/wintercms/wn-ssoprovidermicrosoft-plugin

Type:winter-plugin

pkg:composer/winter/wn-ssoprovidermicrosoft-plugin

Fund package maintenance!

wintercms

Open Collective

Statistics

Installs: 19

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

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

This package is not auto-updated.

Last update: 2026-09-13 10:37:51 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 Directory → App 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 & secrets → New 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 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

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.