Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Oauth2 Azure Laravel Package

thenetworg/oauth2-azure

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require thenetworg/oauth2-azure
    

    Ensure your Laravel project has the PHP League OAuth2 Client installed as a dependency.

  2. Register an Azure AD Application

    • Go to the Azure Portal.
    • Navigate to Azure Active Directory > App registrations > New registration.
    • Configure the app with a redirect URI (e.g., https://your-app.com/auth/callback).
    • Note the Application (client) ID and Directory (tenant) ID.
    • Under Certificates & secrets, create a new client secret or upload a certificate.
  3. Basic Provider Setup

    use TheNetworg\OAuth2\Client\Provider\Azure;
    
    $provider = new Azure([
        'clientId'          => env('AZURE_CLIENT_ID'),
        'clientSecret'      => env('AZURE_CLIENT_SECRET'),
        'redirectUri'       => env('AZURE_REDIRECT_URI'),
        'scopes'            => ['openid', 'profile', 'email'],
    ]);
    
  4. First Use Case: Authorization Code Flow Redirect users to Azure for authentication:

    $authorizationUrl = $provider->getAuthorizationUrl();
    return redirect()->to($authorizationUrl);
    

    Handle the callback:

    $token = $provider->getAccessToken('authorization_code', [
        'code' => request('code'),
    ]);
    $user = $provider->getResourceOwner($token);
    

Implementation Patterns

Workflows

1. User Authentication Flow

  • Redirect to Azure AD:
    $authUrl = $provider->getAuthorizationUrl(['scope' => $provider->getScope()]);
    return redirect()->away($authUrl);
    
  • Handle Callback:
    $token = $provider->getAccessToken('authorization_code', [
        'code' => request('code'),
    ]);
    session()->put('azure_token', $token);
    
  • Fetch User Data:
    $user = $provider->getResourceOwner(session('azure_token'));
    

2. API Requests with Microsoft Graph

  • Initialize Provider with Graph Scope:
    $baseGraphUri = $provider->getRootMicrosoftGraphUri(null);
    $provider->scope = 'openid profile email offline_access ' . $baseGraphUri . '/User.Read';
    
  • Make API Calls:
    $token = session('azure_token');
    $me = $provider->get($provider->getRootMicrosoftGraphUri($token) . '/v1.0/me', $token);
    

3. Token Refresh

if ($token->hasExpired() && $token->getRefreshToken()) {
    $token = $provider->getAccessToken('refresh_token', [
        'refresh_token' => $token->getRefreshToken(),
    ]);
    session()->put('azure_token', $token);
}

4. Logout

$logoutUrl = $provider->getLogoutUrl('https://your-app.com');
return redirect()->away($logoutUrl);

Integration Tips

Laravel Service Provider

Create a dedicated service provider to manage the Azure provider instance:

// app/Providers/AzureAuthServiceProvider.php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use TheNetworg\OAuth2\Client\Provider\Azure;

class AzureAuthServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(Azure::class, function ($app) {
            return new Azure([
                'clientId' => env('AZURE_CLIENT_ID'),
                'clientSecret' => env('AZURE_CLIENT_SECRET'),
                'redirectUri' => env('AZURE_REDIRECT_URI'),
                'scopes' => ['openid', 'profile', 'email'],
            ]);
        });
    }
}

Middleware for Protected Routes

// app/Http/Middleware/AuthenticateWithAzure.php
namespace App\Http\Middleware;

use Closure;
use TheNetworg\OAuth2\Client\Provider\Azure;

class AuthenticateWithAzure
{
    protected $provider;

    public function __construct(Azure $provider)
    {
        $this->provider = $provider;
    }

    public function handle($request, Closure $next)
    {
        if (!$request->user()) {
            $authUrl = $this->provider->getAuthorizationUrl();
            return redirect()->away($authUrl);
        }
        return $next($request);
    }
}

Using Certificates Instead of Secrets

$provider = new Azure([
    'clientId' => env('AZURE_CLIENT_ID'),
    'clientCertificatePrivateKey' => file_get_contents(env('AZURE_CERT_PRIVATE_KEY_PATH')),
    'clientCertificateThumbprint' => env('AZURE_CERT_THUMBPRINT'),
    'redirectUri' => env('AZURE_REDIRECT_URI'),
]);

Gotchas and Tips

Pitfalls

  1. State Validation Always validate the state parameter in the callback to prevent CSRF attacks:

    if (!isset($_GET['state']) || $_GET['state'] !== session('oauth_state')) {
        abort(403, 'Invalid state parameter');
    }
    
  2. Token Expiry Handling Tokens expire quickly (typically 1 hour). Always check for expiry and refresh tokens when making API calls:

    if ($token->hasExpired()) {
        if ($token->getRefreshToken()) {
            $token = $provider->getAccessToken('refresh_token', [
                'refresh_token' => $token->getRefreshToken(),
            ]);
        } else {
            // Redirect to login if no refresh token
            return redirect()->route('login');
        }
    }
    
  3. Scope Configuration

    • For Azure AD v1.0, use resource to specify the API (e.g., https://graph.microsoft.com).
    • For Azure AD v2.0, use scope directly (e.g., openid profile email https://graph.microsoft.com/User.Read).
  4. Redirect URI Mismatch Ensure the redirectUri in your Laravel app matches exactly with the one registered in Azure AD (including https:// and trailing slashes).

  5. Certificate Thumbprint When using certificates, ensure the thumbprint is correctly formatted (e.g., B4A94A83092455AC4D3AC827F02B61646EAAC43D). A single mistake can cause authentication failures.


Debugging

  1. Enable Guzzle Debugging Add this to your provider initialization to log HTTP requests:

    $provider = new Azure([...]);
    $provider->getHttpClient()->getEmitter()->attach(
        new \GuzzleHttp\Middleware::tap(function ($request) {
            \Log::debug('Request:', [
                'url' => (string) $request->getUri(),
                'method' => $request->getMethod(),
                'headers' => $request->getHeaders(),
            ]);
        })
    );
    
  2. Validate Token Manually Use Azure's token validation endpoint to debug token issues:

    curl -X POST "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "client_id={client_id}&client_secret={client_secret}&grant_type=client_credentials"
    
  3. Check Azure AD Logs Navigate to Azure Portal > Azure Active Directory > Monitor > Sign-ins to inspect authentication attempts.


Tips

  1. Use Laravel Sessions for Tokens Store tokens in the session to persist them across requests:

    session()->put('azure_token', $token);
    $token = session('azure_token');
    
  2. Leverage Resource Owner Extract user details easily:

    $user = $provider->getResourceOwner($token);
    $email = $user->getUpn(); // User Principal Name (UPN)
    $name = $user->getFirstName() . ' ' . $user->getLastName();
    
  3. Custom Headers for API Requests Add custom headers (e.g., for Microsoft Graph):

    $headers = ['Accept' => 'application/json', 'Content-Type' => 'application/json'];
    $response = $provider->get('https://graph.microsoft.com/v1.0/me', $token, $headers);
    
  4. B2C Specifics For Azure AD B2C, set custom policies and endpoints:

    $provider->pathAuthorize = "/oauth2/v2.0/authorize";
    $provider->pathToken = "/oauth2/v2.0/token";
    $provider->scope = ["
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views