Введение в базовую сертификацию
В сетевой деятельности аутентификация личности является очень важной частью. Базовая аутентификация — это одна из схем аутентификации, представленных в HTTP 1.0. Хотя схема относительно старая и имеет недостатки в безопасности, она до сих пор используется многими веб-сайтами из-за простой реализации.
В этой статье на примере показано, как реализован протокол базовой проверки подлинности. В то же время обсуждаются недостатки безопасности в базовой аутентификации. Наконец, прикрепите базовый код сервера аутентификации.
Основная идея
Базовая проверка подлинности реализует проверку личности пользователя путем проверки имени пользователя и пароля.
В базовой сертификации наиболее важными 4 элементами являются:
- userid: идентификатор пользователя. Также известен как имя пользователя.
- пароль: Пароль пользователя.
- область: «область» фактически относится к области защиты текущей сертификации.
На этом же сервере находятся различные ресурсы с ограниченным доступом, такие как финансовая информация, конфиденциальные документы и т.д. Различные области могут быть определены для разных ресурсов и разрешать доступ к ним только определенным пользователям.
Это очень похоже на учетную запись и систему группировки в Linux, как показано в следующем примере.
Пример базовой аутентификации
Ниже приведен пример, объясняющий, как реализована обычная проверка подлинности, которая разделена на 4 этапа. Предполагать:
- Ресурсы, к которым обращаются пользователи: /protected_docs
- Имя пользователя, пароль: chyingp, 123456
Шаг 1. Доступ пользователей к ограниченным ресурсам
Таким образом, пользователь получает доступ к ограниченным ресурсам./protected_docs
. Сообщение запроса выглядит следующим образом:
GET /protected_docs HTTP/1.1
Host: 127.0.0.1:3000
Шаг 2: Сервер возвращает 401 для аутентификации.
Сервер обнаруживает, что /protected_docs является ресурсом с ограниченным доступом, поэтому отправляет пользователю код состояния 401 с запросом на аутентификацию.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm=protected_docs
В заголовке ответа передайтеWWW-Authenticate
Сообщите клиенту, что схема аутентификацииbasic
. Одновременно сrealm
Сообщите область сертификации.
WWW-Authenticate: Basic realm=<需要保护资源的范围>
Шаг 3: Пользователь отправляет запрос аутентификации
Получив ответ от сервера, пользователь вводит имя пользователя и пароль, а затем отправляет серверу запрос аутентификации.
Далее следует сообщение запроса.Authorization
Заголовок запроса содержит имя пользователя и пароль, введенные пользователем.
GET /protected_docs HTTP/1.1
Authorization: Basic Y2h5aW5ncDoxMjM0NTY=
Authorization
Формат заголовка такойBasic base64(userid:password)
. Фактический код выглядит следующим образом:
Buffer.from('chyingp:123456').toString('base64'); // Y2h5aW5ncDoxMjM0NTY=
Шаг 4: Сервер проверяет запрос
После получения запроса аутентификации от пользователя сервер проверяет запрос. Валидация состоит из следующих шагов:
- По адресу запрашиваемого пользователем ресурса определяется область, соответствующая ресурсу.
- Разберите заголовок запроса авторизации, чтобы получить имя пользователя и пароль.
- Определите, есть ли у пользователя разрешение на доступ к области.
- Убедитесь, что имя пользователя и пароль совпадают.
После прохождения вышеуказанной проверки ресурс запроса возвращается. Если проверка не удалась, верните 401, чтобы потребовать повторной аутентификации, или верните 403 (Запрещено).
недостаток безопасности
Недостаток безопасности базовой аутентификации очевиден: она передает пароль пользователя в открытом виде, что может привести к серьезным проблемам с безопасностью.
- Без шифрования на транспортном уровне незашифрованный пароль пользователя может быть перехвачен посредником.
- После утечки пароля в открытом виде, если другие сайты пользователя также используют тот же пароль в открытом виде (с высокой вероятностью), линия безопасности других сайтов пользователя также будет нарушена.
Консультации по вышеуказанным вопросам:
- Не используйте обычную аутентификацию, если транспортный уровень не зашифрован.
- Если используется обычная аутентификация, пароль для входа генерируется сервером.
- По возможности не используйте обычную аутентификацию.
Помимо недостатков безопасности, существуют ситуации, в которых базовая сертификация не может быть отозвана.
Пример кода сервера
Серверный код выглядит следующим образом, он относительно прост. Здесь он не будет расширяться. Если у вас есть какие-либо вопросы, вы можете оставить сообщение для связи. Полный код можнокликните сюда.
const express = require('express');
const app = express();
const realms = [
{ realm: 'protected_docs', path: '/protected_docs', users: ['chyingp'] }
];
const users = [
{ usrname: 'chyingp', passwd: '123456' }
];
// 检查资源路径对应的realm,比如 path:'/protected_docs' => realm:'protected_docs'
function findRealm (path) {
return realms.find(item => path.indexOf(item.path) !== -1);
}
// 根据用户名、密码,查找用户
function findUser (usrname, passwd) {
return users.find(user => user.usrname === usrname && user.passwd === passwd);
}
// 判断用户是否在realm里
function isUserInRealm (realmItem, usrname) {
return realmItem.users.indexOf(usrname) !== -1;
}
function notAuthorized (res) {
res.status = 403;
res.end();
}
const protectedPath = '/protected_docs';
app.get(protectedPath, (req, res, next) => {
const realmItem = findRealm(protectedPath);
const realm = realmItem.realm; // 这里是 protected_docs
const authorization = req.get('authorization');
if (authorization) { // 身份认证
const usernamePasswd = authorization.split(' ')[1]; // Basic Y2h5aW5ncDoxMjM0NTY
const [usrname, passwd] = Buffer.from(usernamePasswd, 'base64').toString().split(':');
if (isUserInRealm(realmItem, usrname) === false) { // 用户不在realm里
return notAuthorized(res);
}
const user = findUser(usrname, passwd);
if (!user) { // 用户账号、密码验证不通过
return notAuthorized(res);
}
res.end(`welecom ${usrname}`);
} else { // 告知用户需要身份认证
res.statusCode = 401;
res.set('WWW-Authenticate', 'Basic realm=' + encodeURIComponent(realm));
res.end();
}
});
app.listen(3000);
Ссылка на ссылку
HTTP Authentication: Basic and Digest Access Authentication
Об авторе: Сяока, бывший старший инженер Tencent, в настоящее время возглавляет отдел интерфейсных технологий в Qianhai Yunhan Financial Technology. Сосредоточьтесь на технической архитектуре, обмене технологиями, управлении проектами.