Расширение аутентификации Windows в приложении ASP.NET MVC 3

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

Мне нужно внедрить приложение интрасети для группы разных групп пользователей. До сих пор я использовал аутентификацию Windows, которая была очень проста в реализации. Мои проблемы возникают, когда речь идет о авторизации групп пользователей для специальных функциональных возможностей приложения.

Использование [Authorize(Users = "DOMAIN\\USER")] отлично работает, но из-за этого у меня нет доступа к активному управлению каталогом, мне невозможно настроить rolemanagement таким образом, каким он нужен для моего приложения.

Что я хотел бы сделать, так это определение пользовательских ролей и членства в дополнение к тем, которые определены в активном каталоге (возможно ли такое расширение? Например, путем реализации собственного членства?).

Как вы думаете, это лучшее решение для моей проблемы. Действительно ли мне нужно реализовать сложную аутентификацию в смешанном режиме с аутентификацией форм в дополнение к проверке подлинности Windows?

Используемые технологии:

  • MS SQL Server 2008
  • MS VS 2010
  • ASP.NET MVC 3 - Механизм просмотра Razor
  • Расширения Telerik для ASP.NET MVC
  • IIS 7 на Windows Server 2008

EDIT (окончательное решение благодаря помощи dougajmcdonald):

После указания на использование пользовательской реализации IPrincipal я нашел несколько решений здесь и . Собирая все вместе, я пришел к следующему решению:

1.Создание пользовательской основной реализации:

public class MyPrincipal: WindowsPrincipal
{
    List<string> _roles;

    public MyPrincipal(WindowsIdentity identity) : base(identity) {
        // fill roles with a sample string just to test if it works
        _roles = new List<string>{"someTestRole"}; 
        // TODO: Get roles for the identity out of a custom DB table
    }

    public override bool IsInRole(string role)
    {
        if (base.IsInRole(role) || _roles.Contains(role))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}

2. Внесите мою обычную основную реализацию в приложение через расширение файла "Global.asax.cs":

    protected void Application_AuthenticateRequest(object sender, EventArgs e)
    {
        if (Request.IsAuthenticated)
        {
            WindowsIdentity wi = (WindowsIdentity)HttpContext.Current.User.Identity;
            MyPrincipal mp = new MyPrincipal(wi);
            HttpContext.Current.User = mp;
        }
    }

3.Используйте мои собственные роли для авторизации в моем приложении

public class HomeController : Controller
{
    [Authorize(Roles= "someTestRole")]
    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";

        return View();
    }
}

Это работает!!! да!

Ответ 1

Я не уверен, что это все еще применяется в MVC, но в Webforms один из способов сделать это будет следующим:

  • Создать новую реализацию IPrincipal, возможно, расширение WindowsPrincipal
  • В этом классе дайте ему набор ролей (собственные роли)
  • Заполните эти роли, возможно, извлекая их из БД.
  • Переопределить IsInRole, чтобы вернуть значение true, если предоставленная роль EITI истинна из базового вызова (WindowsAuthentication/Role) ИЛИ из вашей собственной коллекции специальных ролей.

Таким образом, вы все еще можете подключиться к Principal.IsInRole( "MyRole" ), а также к основной аннотации [PrincipalPermission()]. ​​

Надеюсь, что это поможет.

ИЗМЕНИТЬ в ответ на q:

Чтобы интегрировать принципала в авторизацию, вам нужно написать свой собственный метод для OnAuthenticate в global.asax для типа проверки подлинности, поэтому я бы предположил для вас следующее:

void WindowsAuthentication_OnAuthenticate(object sender, WindowsAuthenticationEventArgs e)
{
    // ensure we have a name and made it through authentication
    if (e.Identity != null && e.Identity.IsAuthenticated)
    {
        //create your principal, pass in the identity so you know what permissions are tied to
        MyCustomePrincipal opPrincipal = new MyCustomePrincipal(e.Identity);            
        //assign your principal to the HttpContext.Current.User, or perhaps Thread.Current
        HttpContext.Current.User = opPrincipal;    
    }
}

Я считаю, что Авторитарство позднее появилось в PrincipalPermission, но я не слишком уверен в том, когда/почему из-за различий я боюсь:( - извините!