18

Tengo un proveedor de miembros/roles personalizado que utilizo en mis controladores MVC que también quiero que tenga acceso a ASP.NET MVC, para que pueda usar AuthorizationFilters, etc. Dado que muchas personas han implementado proveedores personalizados, imagino que muchas personas lo han hecho, pero no lo he descubierto o no he encontrado publicaciones que aborden este problema específicamente. This post es una especie de otra cara de mi pregunta. En mi caso, tengo mi proveedor personalizado funcionando bien con mis controladores, y quiero que MVC lo use también.Cómo integrar el proveedor de membresía de IoC con ASP.NET MVC

Mi proveedor está implementado con un diseño de inyección de IoC/dependencia. El proveedor expone una funcionalidad adicional más allá de la API de membresía/roles de referencia. En mis controladores, utilizo Castle Windsor para crear instancias. El código es similar a:

public class HomeController : Controller { 
    IMembershipService _membershipService; 
    public HomeController(IMembershipService membershipService) { 
     _membershipService= membershipService; 
    } 
} 

<castle> 
<components> 
    <component id="MembershipService" 
      service="IMembershipService, MyApp" 
      type="MembershipService, MyApp" lifestyle="PerWebRequest"> 
    <parameters> 
     <connectionString>#{defaultConnectionString}</connectionString> 
    </parameters> 
    </component> 
</components> 
</castle> 

public class WindsorControllerFactory : DefaultControllerFactory { 
    private WindsorContainer _container; 
    public WindsorControllerFactory() { 
     _container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle"))); 

     List<Type> controllerTypes = new List<Type>(); 
     foreach (Type t in Assembly.GetExecutingAssembly().GetTypes()) { 
      if (typeof(IController).IsAssignableFrom(t)) 
       controllerTypes.Add(t); 
     } 

     foreach (Type t in controllerTypes) { 
      // LifestyleType.Transient = new controller instance for each request 
      _container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient); 
     } 
    } 

    protected override IController GetControllerInstance(Type controllerType) { 
     return (IController)_container.Resolve(controllerType); 
    } 

Todo esto funciona muy bien en mi código C#, pero quiero conectar el profesional en MVC utilizar [Autorizar] filtros con él:

[Authorize (Users="user1, user2", Roles="role8")] 
public ViewResult MyResult(int x) { 
    // implement 
} 

Sé que la La forma habitual de decirle a ASP.NET sobre una membresía personalizada o un proveedor de roles está en el archivo web.config como se muestra a continuación, pero si hago esto, ASP.NET intentará llamar al constructor predeterminado, que no funcionará. Cualquier ayuda apreciada.

<membership> 
<providers> 
    <clear/> 
    <add name="MyMembershipProvider" type="MyMembershipProvider"> 
</providers> 
</membership> 

Respuesta

24

La forma más sencilla de conseguir que esto funcione es el uso de mecanismo estándar de ASP.NET de <membership> en web.config. Simplemente déjelo usar el constructor predeterminado pero reemplaza Inicializar() y extraer las dependencias allí. Use this como referencia.

Personalmente, debido a cosas como esta, prefiero evitar el modelo de proveedor por completo, así que utilizo un enfoque similar al de described in the MonoRail docs. En mi humilde opinión es menos hinchado y más flexible. Al final, solo se trata de establecer HttpContext.User con una implementación adecuada de IPrincipal que es lo que usa AuthorizeAttribute.

Recientemente blogged about a solution to do proper IoC with MembershipProviders.

+1

Gracias por esto. Si bien el primer método funciona bien, como dijiste, crear clases IPrincipal/IIdentity personalizadas proporciona más flexibilidad. Por ejemplo, es una ruta corta para crear algunos tipos diferentes de autorización de usuario/función que la que proporciona Forms Authentication. – keithm

+2

Parece que el proyecto webdotnet está moviendo su repositorio a mercurial, el enlace está roto :-( –

+0

webdotnet project up :-) –

Cuestiones relacionadas