Расширение проверки подлинности Windows в приложении ASP.NET MVC 3 - PullRequest
14 голосов
/ 26 января 2012

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

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

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

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

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

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

  • MS SQL Server 2008
  • MS VS2010
  • ASP.NET MVC 3 - Razor View Engine
  • Telerik Extensions для ASP.NET MVC
  • IIS 7 в Windows Server 2008

РЕДАКТИРОВАТЬ (окончательное решение благодаря 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 "file:

    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 Ответ

8 голосов
/ 26 января 2012

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

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

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

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

РЕДАКТИРОВАТЬ в ответ на вопрос:

Чтобы интегрировать принципала в авторизацию, вам нужно написать свой собственный метод для 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;    
    }
}

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

...