配置NGINX适配SAML签名证书:Laravel应用对接Azure SSO实操求助
Hey Andy, let's walk through setting up Azure SAML SSO for your Laravel app on your Ubuntu 18.04 + Nginx server step by step. Since you have full admin access and Nginx is listening on port 80 (with SSL handled separately), here's exactly what you need to do:
Start by creating a dedicated, secure directory to store the files your client provided. Laravel's storage directory is a good choice because it already has proper read/write permissions for the web server:
# Create a subdirectory for SAML assets sudo mkdir -p /var/www/your-app/storage/saml # Copy the client's .cer and XML metadata files into this directory sudo cp /path/to/your/client-files/{your-cert.cer,metadata.xml} /var/www/your-app/storage/saml/ # Set ownership and permissions so Laravel can access them sudo chown -R www-data:www-data /var/www/your-app/storage/saml/ sudo chmod -R 644 /var/www/your-app/storage/saml/
Most Laravel SAML libraries expect certificates in PEM format (the .cer file is likely DER-encoded). Use OpenSSL to convert it:
cd /var/www/your-app/storage/saml openssl x509 -inform der -in your-cert.cer -out saml-cert.pem
You can verify the conversion worked by running openssl x509 -text -noout -in saml-cert.pem—it should display the certificate details clearly.
We'll use the popular aacotroneo/laravel-saml2 package to handle SAML logic (it wraps the robust onelogin/php-saml library under the hood):
Install the package
composer require aacotroneo/laravel-saml2
Publish the configuration file
php artisan vendor:publish --provider="Aacotroneo\Saml2\Saml2ServiceProvider"
Update config/saml2.php
Open the file and tweak these key sections to match your setup:
// Identity Provider (Azure) settings 'idp' => [ 'metadata' => storage_path('saml/metadata.xml'), // Path to the client's XML file 'cert' => storage_path('saml/saml-cert.pem'), // Converted PEM certificate ], // Service Provider (Your App) settings 'sp' => [ 'entityId' => 'https://your-app-domain.com/saml2/metadata', // Must match what the client configured in Azure App Registration 'assertionConsumerService' => [ 'url' => 'https://your-app-domain.com/saml2/acs', // Azure will send SAML responses here ], 'NameIDFormat' => 'urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress', // Match Azure's user identifier format ],
Add SAML routes (if needed)
The package includes default routes, but you can explicitly define them in routes/web.php for clarity:
Route::get('/saml2/login', '\Aacotroneo\Saml2\Http\Controllers\Saml2Controller@login'); Route::post('/saml2/acs', '\Aacotroneo\Saml2\Http\Controllers\Saml2Controller@acs'); Route::get('/saml2/metadata', '\Aacotroneo\Saml2\Http\Controllers\Saml2Controller@metadata');
You need to tell Laravel how to take the user data from Azure's SAML response and log them into your app. We'll use an event listener for this:
Register the listener
Add this to App/Providers/EventServiceProvider.php:
protected $listen = [ \Aacotroneo\Saml2\Events\Saml2LoginEvent::class => [ \App\Listeners\HandleSamlLogin::class, ], ];
Create the listener file
Make App/Listeners/HandleSamlLogin.php:
<?php namespace App\Listeners; use Aacotroneo\Saml2\Events\Saml2LoginEvent; use Illuminate\Support\Facades\Auth; class HandleSamlLogin { public function handle(Saml2LoginEvent $event) { $samlUser = $event->getSaml2User(); $attributes = $samlUser->getAttributes(); // Pull user data from Azure's SAML attributes (adjust keys based on what Azure sends) $email = $attributes['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress'][0]; $name = $attributes['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname'][0] . ' ' . $attributes['http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname'][0]; // Find or create a local user record $localUser = \App\User::firstOrCreate( ['email' => $email], ['name' => $name] ); // Log the user into your app Auth::login($localUser); } }
Note: Azure's attribute keys might vary—use a browser extension like SAML Tracer to inspect the actual SAML response attributes if you run into issues.
Ensure Nginx properly handles the SAML POST request (which can be large) and forwards it to Laravel. Update your app's Nginx config (typically /etc/nginx/sites-available/your-app.conf):
server { listen 80; server_name your-app-domain.com; root /var/www/your-app/public; index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php?$query_string; } # Handle large SAML response payloads location /saml2/acs { try_files $uri $uri/ /index.php?$query_string; client_max_body_size 10M; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.2-fpm.sock; # Ubuntu 18.04 uses PHP 7.2 by default } location ~ /\.ht { deny all; } }
Test the config and restart Nginx:
sudo nginx -t sudo systemctl restart nginx
- Visit
https://your-app-domain.com/saml2/login(once SSL is active) — you should be redirected to Azure's login page. - Use a test account provided by your client to log in. You should be redirected back to your app and automatically authenticated.
- If something breaks, check Laravel's logs at
storage/logs/laravel.logfor errors (common issues include mismatched metadata URLs or invalid certificate paths).
内容的提问来源于stack exchange,提问作者Andy

