Pregunta

Tengo un proveedor de membresía / roles personalizado que uso en mis controladores MVC que también quiero tener accesible para ASP.NET MVC, por lo que puedo usar AuthorizationFilters, etc. Dado que muchas personas han implementado proveedores personalizados, imagino que muchos la gente ha hecho esto pero no lo he resuelto ni he encontrado publicaciones que aborden este problema específicamente. Esta publicación es una especie de otra cara de mi pregunta. En mi caso, mi proveedor personalizado funciona bien con mis controladores y quiero que MVC también lo use.

Mi proveedor se implementa con un diseño de inyección de dependencia / IoC. El proveedor expone una funcionalidad adicional más allá de la API de membresía / roles de referencia. En mis controladores, uso 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 mi proveedor a MVC para usar filtros [Autorizar] con él:

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

Sé que la forma habitual de informarle a ASP.NET sobre una membresía personalizada o un proveedor de roles es en el archivo web.config como se muestra a continuación, pero si lo hago, ASP.NET solo intentará llamar al constructor predeterminado, que ganó ' t trabajo. Cualquier ayuda apreciada.

<membership>
 <providers>
  <clear/>
  <add name="MyMembershipProvider" type="MyMembershipProvider">
 </providers>
</membership>
¿Fue útil?

Solución

La forma más simple de hacer que esto funcione es usar el mecanismo estándar de ASP.NET de <membership> en web.config. Simplemente deja que use el constructor predeterminado pero reemplaza Initialize () y pull las dependencias allí. Utilice esto como referencia.

Personalmente, debido a cosas como esta, prefiero evitar el modelo de proveedor por completo, así que uso un enfoque similar a los descrito en los documentos de MonoRail . En mi humilde opinión es menos hinchado y más flexible. Al final, se trata de configurar HttpContext.User con una correcta IPrincipal implementación que es qué utiliza AuthorizeAttribute.

Recientemente escribió en un blog sobre una solución para hacer una IoC adecuada con MembershipProviders .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top