Fixes #8584, #8654, #8727 - fixes and improvements for saml (#8795)

* Let onelogin/php-saml know to use 'X-Forwarded-*' headers if it is from a trusted proxy

* Gracefully handle the case where openssl_csr_new fails when openssl.cnf is invalid/missing

* Improve ui of saml sp metadata by displaying it's url and a download button
This commit is contained in:
johnson-yi 2020-11-21 13:54:25 +11:00 committed by GitHub
parent 8a38b9d018
commit 0cdd83aabf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 17 deletions

View file

@ -53,8 +53,10 @@ class SamlController extends Controller
if (empty($metadata)) { if (empty($metadata)) {
return response()->view('errors.403', [], 403); return response()->view('errors.403', [], 403);
} }
return response($metadata)->header('Content-Type', 'text/xml'); return response()->streamDownload(function () use ($metadata) {
echo $metadata;
}, 'snipe-it-metadata.xml', ['Content-Type' => 'text/xml']);
} }
/** /**

View file

@ -70,22 +70,27 @@ class SettingsSamlRequest extends FormRequest
]); ]);
$csr = openssl_csr_new($dn, $pkey, ['digest_alg' => 'sha256']); $csr = openssl_csr_new($dn, $pkey, ['digest_alg' => 'sha256']);
$x509 = openssl_csr_sign($csr, null, $pkey, 3650, ['digest_alg' => 'sha256']);
openssl_x509_export($x509, $x509cert); if ($csr) {
openssl_pkey_export($pkey, $privateKey);
$errors = []; $x509 = openssl_csr_sign($csr, null, $pkey, 3650, ['digest_alg' => 'sha256']);
while (($error = openssl_error_string() !== false)) {
$errors[] = $error; openssl_x509_export($x509, $x509cert);
} openssl_pkey_export($pkey, $privateKey);
if (!(empty($x509cert) && empty($privateKey))) { $errors = [];
$this->merge([ while (($error = openssl_error_string() !== false)) {
'saml_sp_x509cert' => $x509cert, $errors[] = $error;
'saml_sp_privatekey' => $privateKey, }
]);
if (!(empty($x509cert) && empty($privateKey))) {
$this->merge([
'saml_sp_x509cert' => $x509cert,
'saml_sp_privatekey' => $privateKey,
]);
}
} else {
$validator->errors()->add('saml_integration', 'openssl.cnf is missing/invalid');
} }
} }

View file

@ -5,6 +5,7 @@ namespace App\Services;
use OneLogin\Saml2\Auth as OneLogin_Saml2_Auth; use OneLogin\Saml2\Auth as OneLogin_Saml2_Auth;
use OneLogin\Saml2\IdPMetadataParser as OneLogin_Saml2_IdPMetadataParser; use OneLogin\Saml2\IdPMetadataParser as OneLogin_Saml2_IdPMetadataParser;
use OneLogin\Saml2\Settings as OneLogin_Saml2_Settings; use OneLogin\Saml2\Settings as OneLogin_Saml2_Settings;
use OneLogin\Saml2\Utils as OneLogin_Saml2_Utils;
use App\Models\Setting; use App\Models\Setting;
use App\Models\User; use App\Models\User;
use Exception; use Exception;
@ -153,6 +154,9 @@ class Saml
$this->_enabled = $setting->saml_enabled == '1'; $this->_enabled = $setting->saml_enabled == '1';
if ($this->isEnabled()) { if ($this->isEnabled()) {
//Let onelogin/php-saml know to use 'X-Forwarded-*' headers if it is from a trusted proxy
OneLogin_Saml2_Utils::setProxyVars(request()->isFromTrustedProxy());
data_set($settings, 'sp.entityId', url('/')); data_set($settings, 'sp.entityId', url('/'));
data_set($settings, 'sp.assertionConsumerService.url', route('saml.acs')); data_set($settings, 'sp.assertionConsumerService.url', route('saml.acs'));
data_set($settings, 'sp.singleLogoutService.url', route('saml.sls')); data_set($settings, 'sp.singleLogoutService.url', route('saml.sls'));

View file

@ -125,6 +125,7 @@ return array(
'saml_sp_acs_url' => 'Assertion Consumer Service (ACS) URL', 'saml_sp_acs_url' => 'Assertion Consumer Service (ACS) URL',
'saml_sp_sls_url' => 'Single Logout Service (SLS) URL', 'saml_sp_sls_url' => 'Single Logout Service (SLS) URL',
'saml_sp_x509cert' => 'Public Certificate', 'saml_sp_x509cert' => 'Public Certificate',
'saml_sp_metadata_url' => 'Metadata URL',
'saml_idp_metadata' => 'SAML IdP Metadata', 'saml_idp_metadata' => 'SAML IdP Metadata',
'saml_idp_metadata_help' => 'You can specify the IdP metadata using a URL or XML file.', 'saml_idp_metadata_help' => 'You can specify the IdP metadata using a URL or XML file.',
'saml_attr_mapping_username' => 'Attribute Mapping - Username', 'saml_attr_mapping_username' => 'Attribute Mapping - Username',

View file

@ -55,6 +55,7 @@
{{ Form::checkbox('saml_enabled', '1', Request::old('saml_enabled', $setting->saml_enabled), [((config('app.lock_passwords')===true)) ? 'disabled ': '', 'class' => 'minimal '. $setting->demoMode, $setting->demoMode]) }} {{ Form::checkbox('saml_enabled', '1', Request::old('saml_enabled', $setting->saml_enabled), [((config('app.lock_passwords')===true)) ? 'disabled ': '', 'class' => 'minimal '. $setting->demoMode, $setting->demoMode]) }}
{{ trans('admin/settings/general.saml_enabled') }} {{ trans('admin/settings/general.saml_enabled') }}
{!! $errors->first('saml_integration', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}<br>
@if (config('app.lock_passwords')===true) @if (config('app.lock_passwords')===true)
<p class="text-warning"><i class="fa fa-lock"></i> {{ trans('general.feature_disabled') }}</p> <p class="text-warning"><i class="fa fa-lock"></i> {{ trans('general.feature_disabled') }}</p>
@endif @endif
@ -82,8 +83,12 @@
{{ Form::textarea('saml_sp_x509cert', $setting->saml_sp_x509cert, ['class' => 'form-control', 'wrap' => 'off', 'readonly']) }} {{ Form::textarea('saml_sp_x509cert', $setting->saml_sp_x509cert, ['class' => 'form-control', 'wrap' => 'off', 'readonly']) }}
<br> <br>
@endif @endif
<!-- SAML SP Metadata URL -->
{{ Form::label('saml_sp_metadata_url', trans('admin/settings/general.saml_sp_metadata_url')) }}
{{ Form::text('saml_sp_metadata_url', route('saml.metadata'), ['class' => 'form-control', 'readonly']) }}
<br>
<p class="help-block"> <p class="help-block">
<a href="{{ route('saml.metadata') }}" target="_blank" class="btn btn-default" style="margin-right: 5px;">View Metadata</a> <a href="{{ route('saml.metadata') }}" target="_blank" class="btn btn-default" style="margin-right: 5px;">Download Metadata</a>
</p> </p>
@endif @endif
{!! $errors->first('saml_enabled', '<span class="alert-msg" aria-hidden="true">:message</span>') !!} {!! $errors->first('saml_enabled', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}