什么可能导致新更改的密码不允许登录?
What could be causing the newly changed password not allowing to login?
我正在使用 Web API 2 和 Identity 2。我使用 Autofac 连接了所有东西。当用户更改他的密码时,新更改的密码不起作用,除非我重新启动 api.
似乎是 Katana 和 Autofac 的问题,但我不确定去哪里找。
Global.asax.cs
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
GlobalConfiguration.Configure(ContainerConfig.Configure);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
...
}
}
ContainerConfig.cs
public class ContainerConfig
{
public static void Configure(HttpConfiguration config)
{
// Configure the application for OAuth based flow
const string publicClientId = "self";
// ContainerConfig Config
var connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
var elasticsearchUrl = ConfigurationManager.AppSettings["ElasticSearchUrl"];
var elasticSearchIndex = ConfigurationManager.AppSettings["ElasticSearchIndex"];
var builder = new ContainerBuilder();
builder.Register(c => new BimDataContext(connectionString)).InstancePerLifetimeScope();
builder.RegisterType<ApplicationUserManager>().AsSelf();
builder.RegisterType<ApplicationRoleManager>().AsSelf();
builder.Register(c => new UserStore<ApplicationUser>(c.Resolve<BimDataContext>())).AsImplementedInterfaces();
builder.Register(c => new RoleStore<IdentityRole>(c.Resolve<BimDataContext>())).AsImplementedInterfaces();
builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).As<IAuthenticationManager>();
builder.Register(c => new IdentityFactoryOptions<ApplicationUserManager>
{
DataProtectionProvider = new DpapiDataProtectionProvider("Oporo.io Identity")
});
builder.RegisterType<SimpleRefreshTokenProvider>().As<IAuthenticationTokenProvider>();
builder.Register(c => new ApplicationOAuthProvider(
publicClientId,
c.Resolve<ApplicationUserManager>(),
c.Resolve<IAuthRepository>()))
.As<IOAuthAuthorizationServerProvider>();
// Register your Web API controllers.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// UoW registration: being explicit
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest();
// Repositories registration
builder.RegisterAssemblyTypes(typeof(ClientRepository).Assembly)
.AsImplementedInterfaces()
.InstancePerDependency();
// Services registration
builder.RegisterAssemblyTypes(typeof(ClientService).Assembly)
.AsImplementedInterfaces()
.InstancePerDependency();
builder.RegisterType<EntityPersistedEventHandler>().As<IEntityPersistedEventHandler>().InstancePerRequest();
builder.RegisterType<COBieIndexingService>().As<ICOBieIndexingService>();
builder.RegisterAssemblyTypes(typeof(ClientSearchService).Assembly)
.Where(t => t.Name.EndsWith("SearchService"))
.WithParameters(new List<Parameter>
{
new NamedParameter("connectionstring", elasticsearchUrl),
new NamedParameter("defaultIndex", elasticSearchIndex),
})
.AsImplementedInterfaces();
builder.RegisterType<IfcFileImportTask>().As<IIfcFileImportTask>();
builder.RegisterType<COBieFileImportTask>().As<ICOBieFileImportTask>();
// Hangfire registration
builder.RegisterType<BackgroundJobClient>().As<IBackgroundJobClient>();
// OPTIONAL: Register the Autofac filter provider.
builder.RegisterWebApiFilterProvider(config);
// Set the dependency resolver to be Autofac.
var container = builder.Build();
JobActivator.Current = new AutofacJobActivator(container);
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
}
ApplicationUserManager.cs
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store,
IdentityFactoryOptions<ApplicationUserManager> options)
: base(store)
{
// Configure validation logic for usernames
this.UserValidator = new UserValidator<ApplicationUser>(this)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
this.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
this.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
}
}
Startup.Auth.cs
public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }
public void ConfigureAuth(IAppBuilder app)
{
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
PublicClientId = "self";
//var provider = (IOAuthAuthorizationServerProvider) GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IOAuthAuthorizationServerProvider));
var provider = GlobalConfiguration.Configuration.DependencyResolver.GetRequestLifetimeScope().Resolve<IOAuthAuthorizationServerProvider>();
//var tokenProvider = (IAuthenticationTokenProvider) GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IAuthenticationTokenProvider));
var tokenProvider = GlobalConfiguration.Configuration.DependencyResolver.GetRequestLifetimeScope().Resolve<IAuthenticationTokenProvider>();
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = provider,
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
RefreshTokenProvider = tokenProvider,
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
}
}
问题与在 ApplicationOAuthProvider 中获取相同的用户管理器实例有关
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var container = GlobalConfiguration.Configuration.DependencyResolver.GetRootLifetimeScope();
using (var scope = container.BeginLifetimeScope())
{
var userManager = scope.Resolve<ApplicationUserManager>();
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties properties = CreateProperties(user.UserName);
properties.Dictionary.Add("as:client_id", context.ClientId ?? string.Empty);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);
}
}
我正在使用 Web API 2 和 Identity 2。我使用 Autofac 连接了所有东西。当用户更改他的密码时,新更改的密码不起作用,除非我重新启动 api.
似乎是 Katana 和 Autofac 的问题,但我不确定去哪里找。
Global.asax.cs
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
GlobalConfiguration.Configure(ContainerConfig.Configure);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
...
}
}
ContainerConfig.cs
public class ContainerConfig
{
public static void Configure(HttpConfiguration config)
{
// Configure the application for OAuth based flow
const string publicClientId = "self";
// ContainerConfig Config
var connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
var elasticsearchUrl = ConfigurationManager.AppSettings["ElasticSearchUrl"];
var elasticSearchIndex = ConfigurationManager.AppSettings["ElasticSearchIndex"];
var builder = new ContainerBuilder();
builder.Register(c => new BimDataContext(connectionString)).InstancePerLifetimeScope();
builder.RegisterType<ApplicationUserManager>().AsSelf();
builder.RegisterType<ApplicationRoleManager>().AsSelf();
builder.Register(c => new UserStore<ApplicationUser>(c.Resolve<BimDataContext>())).AsImplementedInterfaces();
builder.Register(c => new RoleStore<IdentityRole>(c.Resolve<BimDataContext>())).AsImplementedInterfaces();
builder.Register(c => HttpContext.Current.GetOwinContext().Authentication).As<IAuthenticationManager>();
builder.Register(c => new IdentityFactoryOptions<ApplicationUserManager>
{
DataProtectionProvider = new DpapiDataProtectionProvider("Oporo.io Identity")
});
builder.RegisterType<SimpleRefreshTokenProvider>().As<IAuthenticationTokenProvider>();
builder.Register(c => new ApplicationOAuthProvider(
publicClientId,
c.Resolve<ApplicationUserManager>(),
c.Resolve<IAuthRepository>()))
.As<IOAuthAuthorizationServerProvider>();
// Register your Web API controllers.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
// UoW registration: being explicit
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest();
// Repositories registration
builder.RegisterAssemblyTypes(typeof(ClientRepository).Assembly)
.AsImplementedInterfaces()
.InstancePerDependency();
// Services registration
builder.RegisterAssemblyTypes(typeof(ClientService).Assembly)
.AsImplementedInterfaces()
.InstancePerDependency();
builder.RegisterType<EntityPersistedEventHandler>().As<IEntityPersistedEventHandler>().InstancePerRequest();
builder.RegisterType<COBieIndexingService>().As<ICOBieIndexingService>();
builder.RegisterAssemblyTypes(typeof(ClientSearchService).Assembly)
.Where(t => t.Name.EndsWith("SearchService"))
.WithParameters(new List<Parameter>
{
new NamedParameter("connectionstring", elasticsearchUrl),
new NamedParameter("defaultIndex", elasticSearchIndex),
})
.AsImplementedInterfaces();
builder.RegisterType<IfcFileImportTask>().As<IIfcFileImportTask>();
builder.RegisterType<COBieFileImportTask>().As<ICOBieFileImportTask>();
// Hangfire registration
builder.RegisterType<BackgroundJobClient>().As<IBackgroundJobClient>();
// OPTIONAL: Register the Autofac filter provider.
builder.RegisterWebApiFilterProvider(config);
// Set the dependency resolver to be Autofac.
var container = builder.Build();
JobActivator.Current = new AutofacJobActivator(container);
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
}
ApplicationUserManager.cs
public class ApplicationUserManager : UserManager<ApplicationUser>
{
public ApplicationUserManager(IUserStore<ApplicationUser> store,
IdentityFactoryOptions<ApplicationUserManager> options)
: base(store)
{
// Configure validation logic for usernames
this.UserValidator = new UserValidator<ApplicationUser>(this)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
this.PasswordValidator = new PasswordValidator
{
RequiredLength = 6,
RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
this.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
}
}
Startup.Auth.cs
public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }
public void ConfigureAuth(IAppBuilder app)
{
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
PublicClientId = "self";
//var provider = (IOAuthAuthorizationServerProvider) GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IOAuthAuthorizationServerProvider));
var provider = GlobalConfiguration.Configuration.DependencyResolver.GetRequestLifetimeScope().Resolve<IOAuthAuthorizationServerProvider>();
//var tokenProvider = (IAuthenticationTokenProvider) GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IAuthenticationTokenProvider));
var tokenProvider = GlobalConfiguration.Configuration.DependencyResolver.GetRequestLifetimeScope().Resolve<IAuthenticationTokenProvider>();
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = provider,
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),
RefreshTokenProvider = tokenProvider,
// In production mode set AllowInsecureHttp = false
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
}
}
问题与在 ApplicationOAuthProvider 中获取相同的用户管理器实例有关
public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
{
var container = GlobalConfiguration.Configuration.DependencyResolver.GetRootLifetimeScope();
using (var scope = container.BeginLifetimeScope())
{
var userManager = scope.Resolve<ApplicationUserManager>();
ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError("invalid_grant", "The user name or password is incorrect.");
return;
}
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookiesIdentity = await user.GenerateUserIdentityAsync(userManager,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties properties = CreateProperties(user.UserName);
properties.Dictionary.Add("as:client_id", context.ClientId ?? string.Empty);
AuthenticationTicket ticket = new AuthenticationTicket(oAuthIdentity, properties);
context.Validated(ticket);
context.Request.Context.Authentication.SignIn(cookiesIdentity);
}
}