Geo*_*uer 7 asp.net asp.net-mvc asp.net-web-api asp.net-identity
我正在使用Autofac进行Inversion of Control容器,其配置如下
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);
}
Run Code Online (Sandbox Code Playgroud)
我相信这是Autofac与其他容器的事实可能与我所看到的无关.在这里,他们重点线是一个配置上的任何依赖IIdentity从采摘HttpContext.Current.
我这样使用它,这样我就可以随时随地访问当前用户.
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我在过去的项目中使用了这种模式,它运行良好.我正在将它应用于现有项目并看到一个非常奇怪的事情.
ICurrentUser一切正常ICurrentUser的Get,因为实例操作失败,IIdentity尚未从cookie解析,还没有装进去索赔(AuthenticationType == null)!奇怪的是,如果我在实例化WebApi控制器后暂停调试器,我可以HttpContext.Current.User.Identity看到AuthenticationType == "Cookie"并且所有声明都存在.这导致我得出的结论是,某些事情按以下顺序发生
HttpContext身份这当然毫无意义!
所以问题如下
请不要建议我创建一个IdentityProvider迟到的解决方案IIdentity.我理解如何解决这个问题,我不明白为什么会发生这种情况以及如何控制事物的管道顺序.
我稍微修改了你的代码,因为我没有NullIdentity(),而且你CurrentUserProvider没有在这里编译。
我安装了这些软件包:
我的 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);
}
}
Run Code Online (Sandbox Code Playgroud)
你的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;
}
}
Run Code Online (Sandbox Code Playgroud)
因此 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);
}
}
Run Code Online (Sandbox Code Playgroud)
我的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();
}
}
Run Code Online (Sandbox Code Playgroud)
...最后是一个简单的 ApiController,我通过输入localhost/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 "";
}
}
Run Code Online (Sandbox Code Playgroud)
如果我刚刚启动项目(甚至没有登录),我会收到一个 GenericIdentity 对象来支持 IIdentity 接口,看看这个:
当我在方法中进入 (F11) 时Get(), 已IIdentity正确设置GenericIdentity,因为实际上没有人登录应用程序。这就是为什么我认为你实际上并不需要 NullableIdentity。
尝试将您的代码与我的代码进行比较并修复您的代码,以便我们看看它是否有效,然后最终您会发现问题的真正原因是什么,而不仅仅是修复它(我们开发人员喜欢知道为什么某些东西能够正常工作) 。
| 归档时间: |
|
| 查看次数: |
235 次 |
| 最近记录: |