У меня есть хранимая процедура, которая обновляет статус. В зависимости от роли пользователя хранимая процедура имеет код, который может разрешить или запретить изменение статуса. По этой причине мне нужно передать имя роли в хранимую процедуру. Имя моей роли хранится на клиенте в моем коде javascript, но, конечно, мне нужна вторая проверка на сервере. У каждого пользователя есть только одна из трех ролей, и при запросе обновления статуса я могу вызвать один из трех методов в зависимости от роли, которую имеет клиент. Вот что я пробовал.
Я использую WebApi с аутентификацией на основе токенов-носителей и ASP.NET Identity 2.1, и приложение всегда запускается в браузере. Моим пользователям были назначены соответствующие роли.
Я добавляю некоторый код для получения идентификатора пользователя, а затем перехожу к таблице AspNetUserRoles, чтобы получить роль в начале метода. Однако я заметил, что для запуска требуется около 500 миллисекунд. В качестве альтернативы рассматриваю следующее:
[HttpPut]
[Authorize(Roles = "Admin")]
[Route("AdminUpdateStatus/{userTestId:int}/{userTestStatusId:int}")]
public async Task<IHttpActionResult> AdminUpdateStatus(int userTestId, int userTestStatusId)
{
return await UpdateStatusMethod(userTestId, userTestStatusId, "Admin");
}
[HttpPut]
[Authorize(Roles = "Student")]
[Route("StudentUpdateStatus/{userTestId:int}/{userTestStatusId:int}")]
public async Task<IHttpActionResult> StudentUpdateStatus(int userTestId, int userTestStatusId)
{
return await UpdateStatusMethod(userTestId, userTestStatusId, "Student");
}
[HttpPut]
[Authorize(Roles = "Teacher")]
[Route("TeacherUpdateStatus/{userTestId:int}/{userTestStatusId:int}")]
public async Task<IHttpActionResult> TeacherUpdateStatus(int userTestId, int userTestStatusId)
{
return await UpdateStatusMethod(userTestId, userTestStatusId, "Teacher");
}
private async Task<IHttpActionResult> UpdateStatusMethod(int userTestId, int userTestStatusId, string roleName)
{
// Call the stored procedure here and pass in the roleName
}
Это эффективный способ сделать это или, возможно, есть другой более чистый способ. Что мне довольно неясно, так это то, кэширует ли передняя или задняя часть роль пользователя. Я предполагаю, что это сделано или есть какая-то настройка, которая позволит это сделать.
Примечание. Я использую утверждения для отправки информации о роли моему клиенту здесь:
public static AuthenticationProperties CreateProperties(
string userName,
ClaimsIdentity oAuthIdentity,
string firstName,
string lastName,
int organization)
{
IDictionary<string, string> data = new Dictionary<string, string>
{
{ "userName", userName},
{ "firstName", firstName},
{ "lastName", lastName},
{ "organization", organization.ToString()},
{ "roles",string.Join(":",oAuthIdentity.Claims.Where(c=> c.Type == ClaimTypes.Role).Select(c => c.Value).ToArray())}
};
return new AuthenticationProperties(data);
}
Однако мой вопрос здесь относится к серверу и к тому, как я могу проверить в своем методе, находится ли пользователь в определенной роли, не обращаясь к базе данных. Может быть, есть способ сделать это безопасно с помощью утверждений, но я не знаю, как это сделать.
Любая помощь и совет будут высоко оценены.