Как использовать роли со встроенной аутентификацией Windows
Я работаю над веб-приложением, реализованным в ASP.NET MVC 5 с Web API 2.
Я реализовал встроенную проверку подлинности Windows, добавив следующий код в web.config:
<system.web>
<authentication mode="Windows" />
</system.web>
<system.webServer>
<security>
<authentication>
<windowsAuthentication enabled="true"/>
</authentication>
</security>
</system.webServer>
и добавив [Authorize]
аннотация поверх моих контроллеров.
Теперь меня попросили предоставить доступ к некоторым функциям в зависимости от роли пользователя. У меня есть таблица, в которой я храню разрешения пользователей, но я не знаю, как я могу создавать эти роли и связывать с ними нужные разрешения.
Любая помощь будет оценена.
заранее спасибо
[ОБНОВИТЬ]
Основываясь на ответе масона, я немного обновил код.
Добавил следующую строку в web.config:
<roleManager defaultProvider="MyRoleProvider">
<providers>
<add
name="MyRoleProvider"
type="MyApp.App_Start.MyRoleProvider"
applicationName="My Tool" />
</providers>
</roleManager>
MyRoleProvider.cs:
public class MyRoleProvider : RoleProvider
{
private MyEntities db = new MyEntities();
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override string ApplicationName
{
get;
set;
}
public override void CreateRole(string roleName)
{
throw new NotImplementedException();
}
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
{
throw new NotImplementedException();
}
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
{
throw new NotImplementedException();
}
public override string[] GetAllRoles()
{
throw new NotImplementedException();
}
public override string[] GetRolesForUser(string username)
{
throw new NotImplementedException();
}
public override string[] GetUsersInRole(string roleName)
{
throw new NotImplementedException();
}
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
{
throw new NotImplementedException();
}
public override bool IsUserInRole(string username, string roleName)
{
vUser user = db.vUsers.Where(u => u.UserName == username).First();
if (roleName == "User")
{
if (user.IsAllowedToView == true)
{
return true;
}
else
{
return false;
}
}
else if (roleName == "Administrator")
{
if (user.IsAllowedToSubmit == true)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
public override bool RoleExists(string roleName)
{
if (roleName == "User" || roleName == "Administrator")
{
return true;
}
else
{
return false;
}
}
}
Когда я использую [Authorize]
аннотации на мои контроллеры и вызов HttpContext.Current.User.Identity.Name
он возвращает идентификатор, который я использую для входа на мою машину. (Часть AD) Но, если я использую [Authorize(Roles="User")], он снова и снова спрашивает мое имя пользователя и пароль и ничего не принимает. Я установил точки останова для каждого метода в классе MyRoleProvider, но программа не остановилась ни на одном, что заставляет меня думать, что, возможно, это даже не вызов поставщика.
4 ответа
Над каждым контроллером или даже каждым методом внутри контроллера вы можете добавить свою собственную роль авторизации.
[Authorize(Roles="Admin,Doctor")]
public class Investigation : Controller
{
}
ПРИМЕЧАНИЕ. Роли должны быть записаны так же, как они были вставлены в базу данных (с учетом регистра).
public override string[] GetRolesForUser(string username)
{
var userrole = from role in db.roles
where username == role.userID
select role.role1;
if (userrole != null)
return userrole.ToArray();
else
return new string[] { };
//throw new NotImplementedException();
}
эта функция должна быть отредактирована.
Если вы хотите управлять ролями из Active Directory, вы всегда можете создать группы пользователей Active Directory для каждой конкретной роли, а затем использовать [Authorize(Roles="{AD_GROUP_NAME}")]
аннотация поверх вашего контроллера.
В вашей конкретной ситуации (на основе чата) звучит так, что концепция, основанная на ролях, вам не подходит, поскольку ваши разрешения хранятся на уровне пользователя, а не на уровне ролей, и вам не разрешено изменять его работу из-за ограничения компании.
Вместо этого вы должны написать свой собственный фильтр, который вы можете применить к своим методам действий. Этот фильтр, вероятно, должен реализовывать IAuthorizationFilter. Это позволит вам сделать что-то вроде:
[RequirePermissions("Save")]
public ActionResult Save(Data date)
{
Database.Save(data);
return View("Success");
}
И, вероятно, логика проверки того, что у пользователя есть это разрешение, должна быть абстрагирована от общего класса, чтобы вы также могли повторно использовать логику в представлениях.