我有一个带有自定义IXmlRepository的asp.net核心2.1.4应用程序,用于使用ef core + postgres存储应用程序密钥。我使用Docker部署应用程序。
除了在生产中运行时所有POST请求都返回400错误的请求响应外,所有内容都部署并运行正常。一切都很好。
问题与防伪/数据保护设置的设置有关,我认为
当我配置DataProtection和Antiforgery时,这是我的Startup.cs。我已将其编辑得最小,以防万一其他设置可能会干扰。
public class Startup
{
IHostingEnvironment _env;
public Startup(IConfiguration configuration, IHostingEnvironment env)
{
Configuration = configuration;
_env = env;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(options =>
options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection"))
);
services.AddIdentity<User, Role>()
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options =>
{
// Password settings
options.Password.RequireDigit = true;
options.Password.RequiredLength = 8;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = true;
options.Password.RequireLowercase = false;
options.Password.RequiredUniqueChars = 6;
// Lockout settings
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
options.Lockout.MaxFailedAccessAttempts = 10;
options.Lockout.AllowedForNewUsers = true;
// User settings
options.User.RequireUniqueEmail = true;
});
### HERE I SET THE CUSTOM KEY STORE ###
services.AddSingleton<IXmlRepository, EfXmlRepository>();
var sp = services.BuildServiceProvider();
services.AddDataProtection()
.AddKeyManagementOptions(options => options.XmlRepository = sp.GetService<IXmlRepository>());
services.AddMvc(options =>
{
options.OutputFormatters.Add(new HtmlOutputFormatter());
options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
### HERE I SET THE ANTI FORGERY HEADER FOR SOME API CALLS ###
services.AddAntiforgery(x => x.HeaderName = "X-XSRF-TOKEN");
services.AddAuthentication()
.AddCookie()
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "myapp.com",
ValidAudience = "myapp.com",
RequireExpirationTime = false,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SecurityKey"]))
};
});;
services.AddTransient<JwtService>();
services.AddTransient<PaymentProviderService>();
services.AddTransient<SubscriptionService>();
services.AddTransient<IInvalidJwtTokenStore, EfInvalidJwtTokenStore>();
//setup hangfire
GlobalConfiguration.Configuration.UsePostgreSqlStorage(Configuration.GetConnectionString("DefaultConnection"));
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(
routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
}
);
loggerFactory.AddConsole(LogLevel.Information);
}
这是我的ef核心IXmlRepository实现:
public class EfXmlRepository : IXmlRepository
{
AppDbContext _db;
public EfXmlRepository(AppDbContext dbContext)
{
_db = dbContext;
}
public IReadOnlyCollection<XElement> GetAllElements()
{
var list = _db.XmlKeys.ToList().Select(x => XElement.Parse(x.Xml)).ToList();
return list;
}
public void StoreElement(XElement element, string friendlyName)
{
_db.XmlKeys.Add(new XmlKey
{
Xml = element.ToString(SaveOptions.DisableFormatting)
});
_db.SaveChanges();
}
}
日志的早期阶段告诉我:
2018-04-04T18:05:58.950344099Z app[web.1]: fail:
Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery[7]
2018-04-04T18:05:58.950392982Z app[web.1]: An exception was
thrown while deserializing the token.
2018-04-04T18:05:58.950398037Z app[web.1]:
System.InvalidOperationException: The antiforgery token could not be
decrypted. ---> System.Security.Cryptography.CryptographicException:
The key {9b8ab2d0-3ca5-4fcd-af54-b1a6601077af} was not found in the key
ring.
但是当我调整了IXmlRepository的postgres设置时,这个错误就消失了。
以防这是我的Dockerfile
FROM microsoft/dotnet:latest
COPY . /app
WORKDIR /app
ENV ASPNETCORE_URLS http://0.0.0.0:5000
ENV ASPNETCORE_ENVIRONMENT Production
EXPOSE 5000
RUN dotnet restore
RUN dotnet publish -c Release
WORKDIR /app/MyApp.Web
RUN dotnet ef database update
WORKDIR /app/MyApp.Web/bin/Release/netcoreapp2.0/publish
ENTRYPOINT dotnet MyApp.Web.dll
期待听到你的想法。谢谢!