gpt4 book ai didi

asp.net - 为什么在解析 WebApi 时未加载身份但在解析 Mvc Controller 时

转载 作者:行者123 更新时间:2023-12-04 12:53:04 26 4
gpt4 key购买 nike

我正在将 Autofac 用于配置如下的控制反转容器

    public void Configuration(IAppBuilder app) {
configureIoC(app);
configureAuth(app);
}

void configureIoC(IAppBuilder app) {
var b = new ContainerBuilder();
//...
b.Register(c => HttpContext.Current?.User?.Identity
?? new NullIdentity()).InstancePerLifetimeScope();
var container = b.Build();
app.UseAutofacMiddleware(container);
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}

我相信这是 Autofac 与其他容器的对比这一事实可能与我所看到的无关。他们这里的关键线是配置对 IIdentity 的任何依赖项。从 HttpContext.Current 中采摘.

我这样使用它,这样我就可以在任何我想要的地方对当前用户进行 stub 访问。
public interface ICurrentUser {
Task<AppUser> Get();
}
public class CurrentUserProvider : ICurrentUser {
public async Task<AppUser> Get() => await users.FindByNameAsync(currentLogin.GetUserId());

public CurrentUserProvider(AppUserManager users, IIdentity currentLogin) {
this.users = users;
this.currentLogin = currentLogin;
}

}

我在过去的项目中使用过这种模式并且效果很好。我目前正在将其应用于现有项目并看到一个非常奇怪的事情。
  • 当一个 Asp.net Mvc Controller 取决于 ICurrentUser一切正常
  • 当一个 WebAPI Controller 获得 ICurrentUser 的实例Get由于 IIdentity 的实例,操作失败尚未从 cookie 中解析出来,并且尚未将声明加载到其中 (AuthenticationType == null)!奇怪的是,如果我在 WebApi Controller 实例化后暂停调试器,我可以点击 HttpContext.Current.User.Identity看看 AuthenticationType == "Cookie"所有的 claim 都在那里。

  • 这使我得出的结论是,不知何故,事情正在按以下顺序发生
  • 如果这是一个 Web API 路由,Web Api Controller 会创建一个实例
  • Asp.Net Identity 填写当前HttpContext身份
  • 如果这是一条 mvc 路由,mvc Controller 会创建一个实例
  • 执行任何操作

  • 这当然毫无意义!

    所以问题如下
  • 我对管道中事物顺序的推断是否正确?
  • 我怎样才能控制它正常工作?为什么这会在其他项目上起作用,但会在这里造成问题?我是否以错误的顺序连接了一些东西?

  • 请不要建议我创建 IdentityProvider后期解决 IIdentity .我了解如何解决此问题,我不明白为什么会发生这种情况以及如何控制事物的管道顺序。

    最佳答案

    我只是稍微修改了你的代码,因为我没有 NullIdentity()和你的CurrentUserProvider没有在这里编译。

    我安装了这些软件包:

  • Autofac
  • Autofac.Owin
  • Autofac.Owin
  • Autofac.Mvc5
  • Autofac.Mvc5.Owin
  • Autofac.WebApi2
  • Autofac.WebApi2.Owin

  • 我的 Startup.cs 看起来像这样:
    public partial class Startup
    {
    public void Configuration(IAppBuilder app)
    {
    configureIoC(app);
    ConfigureAuth(app);
    }

    void configureIoC(IAppBuilder app) {

    var b = new ContainerBuilder();
    //...
    b.RegisterType<CurrentUserProvider>().As <ICurrentUser>().InstancePerLifetimeScope();
    b.Register(c => HttpContext.Current.User.Identity).InstancePerLifetimeScope();

    b.RegisterControllers(typeof(MvcApplication).Assembly);
    b.RegisterApiControllers(typeof(MvcApplication).Assembly);

    var x = new ApplicationDbContext();
    b.Register<ApplicationDbContext>(c => x).InstancePerLifetimeScope();
    b.Register<UserStore<ApplicationUser>>(c => new UserStore<ApplicationUser>(x)).AsImplementedInterfaces().InstancePerLifetimeScope();
    b.RegisterType<ApplicationUserManager>().InstancePerLifetimeScope();
    b.RegisterType<ApplicationSignInManager>().InstancePerLifetimeScope();

    var container = b.Build();

    app.UseAutofacMiddleware(container);
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);

    }

    }

    您的 ICurrentUser东西:
    public interface ICurrentUser
    {
    Task <ApplicationUser> Get();
    }

    public class CurrentUserProvider : ICurrentUser
    {

    private ApplicationUserManager users;
    private IIdentity currentLogin;

    public async Task<ApplicationUser> Get()
    {
    return await users.FindByNameAsync(currentLogin.GetUserId());
    }

    public CurrentUserProvider(ApplicationUserManager users, IIdentity currentLogin)
    {
    this.users = users;
    this.currentLogin = currentLogin;
    }

    }

    因此 Global.asax:
    public class MvcApplication : System.Web.HttpApplication
    {
    protected void Application_Start()
    {
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
    }

    我的 HomeController这很简单:
    public class HomeController : Controller
    {

    private ICurrentUser current;

    public HomeController(ICurrentUser current)
    {
    this.current = current;
    }

    public ActionResult Index()
    {
    var user = current.Get();
    if (user == null)
    throw new Exception("user is null");
    return View();
    }

    }

    ...最后是一个简单的 ApiController,我可以通过键入 访问它本地主机/api/TestApi/5 :
    public class TestApiController : ApiController
    {

    private ICurrentUser current;

    public TestApiController(ICurrentUser current)
    {
    this.current = current;
    }

    public string Get(int id)
    {
    var user = current.Get();
    if (user == null)
    throw new Exception("user is null");
    return "";
    }

    }

    如果我只是启动项目(甚至没有登录),我会收到一个支持 IIdentity 接口(interface)的 GenericIdentity 对象,看看这个:

    Debugging

    当我在 Get() 中踏入 (F11) 时方法, IIdentity正确设置 GenericIdentity ,因为实际上没有人登录应用程序。这就是为什么我认为您实际上并不需要 NullableIdentity。

    enter image description here

    尝试将您的代码与我的代码进行比较并修复您的代码,以便我们查看它是否有效,最终您会发现 是什么真正的原因问题,而不是仅仅修复它(我们开发人员喜欢知道为什么某些东西刚刚开始工作)。

    关于asp.net - 为什么在解析 WebApi 时未加载身份但在解析 Mvc Controller 时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34710057/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com