#asp.net-mvc #url-routing
#asp.net-mvc #url-маршрутизация
Вопрос:
использование asp mvc 4.
Когда пользователь переходит к записи учащегося, URL-адрес говорит:
http://studentTracker.org/Record/Student?studentId=380
В настоящее время пользователь может изменить идентификатор студента прямо в URL-адресе и получить эту запись students, если она не существует. Как я могу либо скрыть часть строки запроса URL-адреса, либо обнаружить / проверить на контроллере, если пользователь изменил URL-адрес?
Комментарии:
1. Я не работаю с asp, но попробуйте сохранить идентификатор пользователя в переменной сеанса или файле cookie, а затем сравнить значение сохраненной переменной со значением
studentId
. Если они не совпадают, перенаправьте пользователя куда-нибудь.
Ответ №1:
Во-первых, вы не можете запретить пользователю что-либо делать, особенно что-то вроде изменения идентификатора в URL. Что вы можете сделать, так это убедиться, что если они это сделают, они получат что-то вроде 404 или 403 вместо фактического содержимого.
Способ сделать это — выполнить разрешение на уровне объекта, что в основном просто означает привязку объекта к пользователям, которым разрешено каким-либо образом просматривать / редактировать его. Обычно это делается с помощью внешнего ключа для чего-то вроде вашего объекта «user» или чего-то более широкого, например, группы или роли.
Например, если запись «Student 380» принадлежит jdoe
, то вы можете запретить доступ к ней кому-либо, но jdoe
сначала добавив внешний ключ к вашей сущности «user» в вашей сущности «student». (Предполагается, что идентификатор не указан):
public class Student
{
...
[ForeignKey("Owner")]
public string OwnerId { get; set; }
public virtual ApplicationUser Owner { get; set; }
}
Затем в вашем действии вместо запроса только по идентификатору вы запрашиваете как идентификатор в URL, так и идентификатор аутентифицированного пользователя:
var userId = User.Identity.GetUserId();
var student = db.Students.SingleOrDefault(m => m.Id == studentId amp;amp; m.OwnerId == userId);
if (student == null)
{
return new HttpNotFoundResult();
}
Теперь, если пользователь изменяется studentId
, но не установлен в качестве «владельца» соответствующего учащегося, он получит 404.
Комментарии:
1. Итак, в этой ситуации люди, которые могут просматривать записи учащихся, являются консультантами, и они оба имеют доступ ко всем записям учащихся. Таким образом, нет никаких оснований для того, чтобы они не могли этого сделать, на самом деле это нормально, что касается бизнес-правил. Просто кажется ужасно небезопасным, зачем вообще получать данные. Я имею в виду, нельзя ли скрыть параметры в заголовке или что-то в GET, чтобы они не были видны в URL?
2. Нет. HTTP работает не так. URI — это «уникальный идентификатор ресурса», здесь это то,
studentId
что делает его уникальным и позволяет серверу возвращать конкретного учащегося. Это также не «небезопасно». Во-первых, что-то вроде идентификатора не имеет собственного значения вне таблицы базы данных, и если кто-то может видеть таблицу базы данных, у вас есть гораздо более насущные проблемы, чем предоставление идентификатора в URL. Поскольку пользователь может манипулировать им, приложение всегда должно защитить себя от таких манипуляций, выполнив что-то вроде того, что я описал здесь.3. установите для типа данных studentid значение guid, при котором будет очень сложно установить параметр вручную и получить информацию о пользователе