如何将 IoC 成员资格提供程序与 ASP.NET MVC 集成

发布于 2024-07-24 22:47:54 字数 2435 浏览 0 评论 0原文

我有一个在 MVC 控制器中使用的自定义成员资格/角色提供程序,我也希望可以访问 ASP.NET MVC,因此我可以使用 AuthorizationFilters 等。由于很多人都实现了自定义提供程序,我想很多人都已经这样做了但我还没有弄清楚或找到专门解决这个问题的帖子。 这篇文章是我的问题的另一面。 就我而言,我的自定义提供程序与我的控制器配合良好,并且我希望 MVC 也使用它。

我的提供程序是通过 IoC/依赖注入设计实现的。 该提供程序公开了超出基线成员资格/角色 API 的附加功能。 在我的控制器中,我使用 Castle Windsor 来创建实例。 代码看起来类似于:

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);
    }

这一切在我的 C# 代码中都运行良好,但我想将我的提供程序连接到 MVC 以使用 [Authorize] 过滤器:

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

我知道告诉 ASP.NET 有关自定义成员资格或角色提供程序的常用方法位于 web.config 文件中,如下所示,但如果我这样做,ASP.NET 将仅尝试调用默认构造函数,这是行不通的。 任何帮助表示赞赏。

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

I have a custom membership/roles provider that I use in my MVC controllers that I also want to have accessible to ASP.NET MVC, so I can use AuthorizationFilters, etc. Since so many people have implemented custom providers I imagine many people have done this but I haven't figured it out or found postings that address this problem specifically. This post is sort of a flip side of my question. In my case I have my custom provider working well with my controllers, and I want MVC to use it too.

My provider is implemented with a IoC/dependency injection design. The provider exposes additional functionality beyond the baseline membership/roles API. In my controllers, I use Castle Windsor to create instances. The code looks similar to:

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);
    }

This all works great in my C# code but I want to wire my provider into MVC to use [Authorize] filters with it:

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

I know that the usual way to tell ASP.NET about a custom membership or roles provider is in the web.config file as below but if I do this ASP.NET will just try to call the default constructor, which won't work. Any help appreciated.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

就此别过 2024-07-31 22:47:54

实现此功能的最简单方法是在 web.config 中使用 ASP.NET 的标准机制 。 您只需让它使用默认构造函数您可以重写Initialize() 并那里的依赖项。 使用作为参考。

就我个人而言,由于这样的事情,我更喜欢完全避免提供者模型,因此我使用类似于 MonoRail 文档中描述。 恕我直言,它不那么臃肿并且更灵活。 最后,只需设置 HttpContext.User 具有适当的 IPrincipal 实现,即AuthorizeAttribute 使用什么。

我最近在博客中介绍了使用 MembershipProviders 进行正确 IoC 的解决方案

The simplest way to get this to work is to use ASP.NET's standard mechanism of <membership> in web.config. You just let it use the default constructor but you override Initialize() and pull the dependencies there. Use this as reference.

Personally, due to things like this, I prefer to avoid the provider model altogether so I use an approach similar to the ones described in the MonoRail docs. IMHO it's less bloated and more flexible. In the end, it's just about setting HttpContext.User with a proper IPrincipal implementation which is what the AuthorizeAttribute uses.

I recently blogged about a solution to do proper IoC with MembershipProviders.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文