Был проект на Laravel 5.5 с пользовательской авторизацией, построенной на основе стандартной авторизации с использованием сессий. Теперь нам нужно включить прозрачную авторизацию на основе adldap. Для реализации мы выбрали согласование авторизации.
Сценарий таков: если человек находится в домене, он автоматически входит на сайт. Если человек находится за пределами доменной зоны, страница входа в веб-авторизацию отображается как ошибка 403. Nginx настроено. Авторизация через интернет тоже работает.
В результате мы получаем следующие параметры:
- Если включена авторизация домена и компьютер находится в доменной зоне, авторизация прошла успешно и все работает.
- Если авторизация домена отключена и пользователь вошел в систему через веб-форму, все работает как положено.
- Если авторизация домена включена, но пользователь вошел в систему через веб-форму, то он будет зарегистрирован, но все файлы из папки publi c (js, css, изображения) возвращает ошибку 404 (NotFoundHttpException в Laravel).
Вот конфигурация nginx
server {
listen 80;
server_name site.local;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name site.local;
ssl on;
ssl_protocols TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384;
ssl_prefer_server_ciphers on;
ssl_ecdh_curve secp384r1;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
ssl_certificate /etc/nginx/sslkey/site.crt;
ssl_certificate_key /etc/nginx/sslkey/site.pem;
ssl_stapling off;
ssl_stapling_verify on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=15768000; includeSubdomains;";
root /var/www/html/site/public;
index index.php index.html index.htm;
location / {
auth_basic off;
auth_gss on;
auth_gss_realm SITE.LOCAL;
auth_gss_keytab /etc/http1.keytab;
auth_gss_service_name HTTP/site.local;
auth_gss_allow_basic_fallback off;
index index.php index.html;
try_files $uri $uri/ /index.php?$args;
error_page 403 = /signin;
autoindex on;
}
location = /signin {
proxy_pass https://site.local/signin;
proxy_set_header Host $http_host;
proxy_pass_request_body off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X_Real-IP $remote_addr;
proxy_set_header X-Original-URI $request_uri;
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/run/php/php7.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 600;
allow all;
}
location /ws/ {
proxy_pass https://127.0.0.1:6002/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $remote_addr;
}
if ($request_method !~ ^(GET|PUT|POST)$ ) {
return 444;
}
location ~* /\.ht { deny all; }
location ~* /\.(svn|hg|git) { deny all; }
location ~ /.well-known {
allow all;
}
}
Маршруты:
Route::get('/login', ['as' => 'login', 'uses' => '\MyPackage\Ldap\Controllers\Auth\ControllerLogin@login']);
Route::match(['get','post'], '/signin', ['before' => 'throttle:2,60', 'as' => 'signin', 'uses' => '\MyPackage\Ldap\Controllers\Auth\ControllerLogin@signin']);
MyPackage \ Ldap \ Controllers \ Auth:
public function login(Request $request)
{
$user = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';
if(!empty($user)){
$manager = Manager::whereName($user)->first();
if ($manager !== null){
$login_session = LoginSession::loginUser($manager, null, null);
return redirect($login_session->getStartPage());
}
}
return redirect()->route('signin');
}
public function signin(Request $request)
{
if ($request->isMethod('get')) return view('vendor/ldap/signin');
$name = $request->input('name');
$pass = $request->input('password');
if (empty($name)) return view('vendor/ldap/signin', ['error' => array('name'=>'Enter your username')]);
if (empty($pass)) return view('vendor/ldap/signin', ['error' => array('password'=>'Enter your password')]);
if (empty($errors)){
$manager = Manager::whereName($name)->first();
if ($manager === null) return redirect()->route('login', ['error' => array('name'=>'No user with this username was found')]);
$hash = abracadabra($pass));
if (strtolower($manager->DIGEST) != $hash) return view('vendor/ldap/signin', ['error' => array('password'=>'The password doesn't match, try again')]);
}
$login_session = LoginSession::loginUser($manager, null, null);
return redirect($login_session->getStartPage());
}
класс LoginSession
protected static function getAuthGuard()
{
return \Auth::guard(config('ldap.auth.guard'));
}
public static function loginUser($user, $dealer_id = null, $role_id = null, $workstation = '')
{
$logged_in_users = LoggedInUser::where('manager_id', $user->IDENTIFIER)->get();
// Unauthorize all users who selected this user
foreach ($logged_in_users as $logged_in_user) {
self::initByLoggedInUser($logged_in_user)->logout();
}
self::getAuthGuard()->loginUsingId($user->IDENTIFIER);
$login_session = self::initByLoggedInUser(
LoggedInUser::create([
'session_id' => Uuid::generate()->string,
'dealer_id' => $dealer_id,
'manager_id' => $user->IDENTIFIER,
'role_id' => $role_id,
'workstation' => $workstation
])
);
$login_session->setSession(self::KEY_MANAGER_ID, $user->IDENTIFIER);
return $login_session;
}
protected function setSession($key, $val)
{
return session()->put($this->getFullSessionKey($key), $val);
}
В чем может быть проблема, как ее решить?