Authentication via REMOTE_USER (#5142)

* Added authentication via Remote User

* - Removed nullable from remote_user settings fileds and used just default values instead
- Removed german translations
- Removed 401 error page and replaced usage with 403 error page as 401 was actual a duplicate of 403
- Replaced usage of $_SERVER['REMOTE_USER'] with Laravels API Request::server('REMOVE_USER')

* - Fixed request usage
This commit is contained in:
David Kaatz 2018-03-14 04:07:52 +01:00 committed by snipe
parent 01eaf48471
commit a43b31400f
7 changed files with 163 additions and 18 deletions

View file

@ -50,17 +50,36 @@ class LoginController extends Controller
\Session::put('backUrl', \URL::previous()); \Session::put('backUrl', \URL::previous());
} }
function showLoginForm(Request $request)
function showLoginForm()
{ {
$this->loginViaRemoteUser($request);
if (Auth::check()) { if (Auth::check()) {
return redirect()->intended('dashboard'); return redirect()->intended('dashboard');
} }
if (Setting::getSettings()->login_common_disabled == "1") {
return view('errors.403');
}
return view('auth.login'); return view('auth.login');
} }
private function loginViaRemoteUser(Request $request)
{
$remote_user = $request->server('REMOTE_USER');
if (Setting::getSettings()->login_remote_user_enabled == "1" && isset($remote_user) && !empty($remote_user)) {
LOG::debug("Authenticatiing via REMOTE_USER.");
try {
$user = User::where('username', '=', $remote_user)->whereNull('deleted_at')->first();
LOG::debug("Remote user auth lookup complete");
if(!is_null($user)) Auth::login($user, true);
} catch(Exception $e) {
LOG::error("There was an error authenticating the Remote user: " . $e->getMessage());
}
}
}
private function login_via_ldap(Request $request) private function loginViaLdap(Request $request)
{ {
LOG::debug("Binding user to LDAP."); LOG::debug("Binding user to LDAP.");
$ldap_user = Ldap::findAndBindUserLdap($request->input('username'), $request->input('password')); $ldap_user = Ldap::findAndBindUserLdap($request->input('username'), $request->input('password'));
@ -114,6 +133,10 @@ class LoginController extends Controller
*/ */
public function login(Request $request) public function login(Request $request)
{ {
if (Setting::getSettings()->login_common_disabled == "1") {
return view('errors.403');
}
$validator = $this->validator(Input::all()); $validator = $this->validator(Input::all());
if ($validator->fails()) { if ($validator->fails()) {
@ -134,7 +157,7 @@ class LoginController extends Controller
if (Setting::getSettings()->ldap_enabled=='1') { if (Setting::getSettings()->ldap_enabled=='1') {
LOG::debug("LDAP is enabled."); LOG::debug("LDAP is enabled.");
try { try {
$user = $this->login_via_ldap($request); $user = $this->loginViaLdap($request);
Auth::login($user, true); Auth::login($user, true);
// If the user was unable to login via LDAP, log the error and let them fall through to // If the user was unable to login via LDAP, log the error and let them fall through to
@ -252,7 +275,15 @@ class LoginController extends Controller
public function logout(Request $request) public function logout(Request $request)
{ {
$request->session()->forget('2fa_authed'); $request->session()->forget('2fa_authed');
Auth::logout(); Auth::logout();
$settings = Setting::getSettings();
$customLogoutUrl = $settings->login_remote_user_custom_logout_url ;
if ($settings->login_remote_user_enabled == '1' && $customLogoutUrl != '') {
return redirect()->away($customLogoutUrl);
}
return redirect()->route('login')->with('success', 'You have successfully logged out!'); return redirect()->route('login')->with('success', 'You have successfully logged out!');
} }

View file

@ -485,6 +485,12 @@ class SettingsController extends Controller
$setting->pwd_secure_min = (int) $request->input('pwd_secure_min'); $setting->pwd_secure_min = (int) $request->input('pwd_secure_min');
$setting->pwd_secure_complexity = ''; $setting->pwd_secure_complexity = '';
# remote user login
$setting->login_remote_user_enabled = (int)$request->input('login_remote_user_enabled');
$setting->login_common_disabled= (int)$request->input('login_common_disabled');
$setting->login_remote_user_custom_logout_url = $request->input('login_remote_user_custom_logout_url');
if ($request->has('pwd_secure_complexity')) { if ($request->has('pwd_secure_complexity')) {
$setting->pwd_secure_complexity = implode('|', $request->input('pwd_secure_complexity')); $setting->pwd_secure_complexity = implode('|', $request->input('pwd_secure_complexity'));
} }

View file

@ -13,15 +13,15 @@ class Setting extends Model
use ValidatingTrait; use ValidatingTrait;
protected $rules = [ protected $rules = [
"brand" => 'required|min:1|numeric', 'brand' => 'required|min:1|numeric',
"qr_text" => 'max:31|nullable', 'qr_text' => 'max:31|nullable',
"logo_img" => 'mimes:jpeg,bmp,png,gif', 'logo_img' => 'mimes:jpeg,bmp,png,gif',
"alert_email" => 'email_array|nullable', 'alert_email' => 'email_array|nullable',
"default_currency" => 'required', 'default_currency' => 'required',
"locale" => 'required', 'locale' => 'required',
"slack_endpoint" => 'url|required_with:slack_channel|nullable', 'slack_endpoint' => 'url|required_with:slack_channel|nullable',
"slack_channel" => 'regex:/(?<!\w)#\w+/|required_with:slack_endpoint|nullable', 'slack_channel' => 'regex:/(?<!\w)#\w+/|required_with:slack_endpoint|nullable',
"slack_botname" => 'string|nullable', 'slack_botname' => 'string|nullable',
'labels_per_page' => 'numeric', 'labels_per_page' => 'numeric',
'labels_width' => 'numeric', 'labels_width' => 'numeric',
'labels_height' => 'numeric', 'labels_height' => 'numeric',
@ -34,11 +34,14 @@ class Setting extends Model
'labels_fontsize' => 'numeric|min:5', 'labels_fontsize' => 'numeric|min:5',
'labels_pagewidth' => 'numeric|nullable', 'labels_pagewidth' => 'numeric|nullable',
'labels_pageheight' => 'numeric|nullable', 'labels_pageheight' => 'numeric|nullable',
"thumbnail_max_h" => 'numeric|max:500|min:25', 'login_remote_user_enabled' => 'numeric|nullable',
"pwd_secure_min" => "numeric|required|min:5", 'login_common_disabled' => 'numeric|nullable',
"audit_warning_days" => "numeric|nullable", 'login_remote_user_custom_logout_url' => 'string|nullable',
"audit_interval" => "numeric|nullable", 'thumbnail_max_h' => 'numeric|max:500|min:25',
"custom_forgot_pass_url" => "url|nullable", 'pwd_secure_min' => 'numeric|required|min:5',
'audit_warning_days' => 'numeric|nullable',
'audit_interval' => 'numeric|nullable',
'custom_forgot_pass_url' => 'url|nullable',
]; ];
protected $fillable = ['site_name','email_domain','email_format','username_format']; protected $fillable = ['site_name','email_domain','email_format','username_format'];

View file

@ -0,0 +1,34 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddRemoteUserSettings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->boolean('login_remote_user_enabled')->default(0);
$table->boolean('login_common_disabled')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('login_remote_user_enabled');
$table->dropColumn('login_common_disabled');
});
}
}

View file

@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddCustomLogoutUrl extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function (Blueprint $table) {
$table->string('login_remote_user_custom_logout_url')->default("");
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function (Blueprint $table) {
$table->dropColumn('login_remote_user_custom_logout_url');
});
}
}

View file

@ -78,6 +78,13 @@ return array(
'load_remote_help_text' => 'This Snipe-IT install can load scripts from the outside world.', 'load_remote_help_text' => 'This Snipe-IT install can load scripts from the outside world.',
'login_note' => 'Login Note', 'login_note' => 'Login Note',
'login_note_help' => 'Optionally include a few sentences on your login screen, for example to assist people who have found a lost or stolen device. This field accepts <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>', 'login_note_help' => 'Optionally include a few sentences on your login screen, for example to assist people who have found a lost or stolen device. This field accepts <a href="https://help.github.com/articles/github-flavored-markdown/">Github flavored markdown</a>',
'login_remote_user_text' => 'Remote User login options',
'login_remote_user_enabled_text' => 'Enable Login with Remote User Header',
'login_remote_user_enabled_help' => 'This option enables Authentication via the REMOTE_USER header according to the "Common Gateway Interface (rfc3875)"',
'login_common_disabled_text' => 'Disable other authentication mechanisms',
'login_common_disabled_help' => 'This option disables other authentication mechanisms. Just enable this option if you are sure that your REMOTE_USER login is already working',
'login_remote_user_custom_logout_url_text' => 'Custom logout URL',
'login_remote_user_custom_logout_url_help' => 'If filled users will get redirected to this URL after the Session of SnipeIT is closed (Logout). This is usefull to close the user sessions of your Authenticationprovider correctly.',
'logo' => 'Logo', 'logo' => 'Logo',
'full_multiple_companies_support_help_text' => 'Restricting users (including admins) assigned to companies to their company\'s assets.', 'full_multiple_companies_support_help_text' => 'Restricting users (including admins) assigned to companies to their company\'s assets.',
'full_multiple_companies_support_text' => 'Full Multiple Companies Support', 'full_multiple_companies_support_text' => 'Full Multiple Companies Support',

View file

@ -35,6 +35,38 @@
<div class="col-md-11 col-md-offset-1"> <div class="col-md-11 col-md-offset-1">
<!-- Remote User Authentication -->
<div class="form-group {{ $errors->has('login_remote_user') ? 'error' : '' }}">
<div class="col-md-3">
{{ Form::label('login_remote_user', trans('admin/settings/general.login_remote_user_text')) }}
</div>
<div class="col-md-9">
<!-- Enable Remote User Login -->
{{ Form::checkbox('login_remote_user_enabled', '1', Input::old('login_remote_user_enabled', $setting->login_remote_user_enabled),array('class' => 'minimal')) }}
{{ Form::label('login_remote_user_enabled', trans('admin/settings/general.login_remote_user_enabled_text')) }}
{!! $errors->first('login_remote_user_enabled', '<span class="alert-msg">:message</span>') !!}
<p class="help-block">
{{ trans('admin/settings/general.login_remote_user_enabled_help') }}
</p>
<!-- Custom logout url to redirect to authentication provider -->
{{ Form::label('login_remote_user_custom_logout_url', trans('admin/settings/general.login_remote_user_custom_logout_url_text')) }}
{{ Form::text('login_remote_user_custom_logout_url', Input::old('login_remote_user_custom_logout_url', $setting->login_remote_user_custom_logout_url),array('class' => 'form-control')) }}
{!! $errors->first('login_remote_user_custom_logout_url', '<span class="alert-msg">:message</span>') !!}
<p class="help-block">
{{ trans('admin/settings/general.login_remote_user_custom_logout_url_help') }}
</p>
<!-- Disable other logins mechanism -->
{{ Form::checkbox('login_common_disabled', '1', Input::old('login_common_disabled', $setting->login_common_disabled),array('class' => 'minimal')) }}
{{ Form::label('login_common_disabled', trans('admin/settings/general.login_common_disabled_text')) }}
{!! $errors->first('login_common_disabled', '<span class="alert-msg">:message</span>') !!}
<p class="help-block">
{{ trans('admin/settings/general.login_common_disabled_help') }}
</p>
</div>
</div>
<!-- Two Factor --> <!-- Two Factor -->
<div class="form-group {{ $errors->has('brand') ? 'error' : '' }}"> <div class="form-group {{ $errors->has('brand') ? 'error' : '' }}">
<div class="col-md-3"> <div class="col-md-3">