Как использовать роли со встроенной аутентификацией 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");
}

И, вероятно, логика проверки того, что у пользователя есть это разрешение, должна быть абстрагирована от общего класса, чтобы вы также могли повторно использовать логику в представлениях.

Другие вопросы по тегам