将 asp.net Core REACT 应用程序部署到 AWS Beanstalk 时 IdentityServer 出错
Error with IdentityServer when deploying asp.net Core REACT app to AWS Beanstalk
我有一个 asp.net 核心应用程序,其 React 前端使用 IdentityServer。它是在 Visual Studio 2019 年使用脚手架模板创建的。该应用程序在本地运行良好,但在我部署到 AWS beanstalk 时失败。它失败的代码行在我的 Startup.cs
的 Configure
方法中。 app.UseIdentityServer()
.
在 UseIdentityServer()
的某处有一个我看不到的空引用异常,在我的开发机器上进行本地测试时我无法重现。
这是我在 Startup.cs
中的 Configure()
方法:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
//app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
//spa.UseReactDevelopmentServer(npmScript: "start"); // Starts CRA automatically
spa.UseProxyToSpaDevelopmentServer("http://localhost:3000"); // Must manually start CRA (yarn start)
}
});
}
}
我在检查 AWS beantalk 日志时遇到如下错误:
Jan 1 00:36:57 ip-172-30-2-135 web: #033[41m#033[30mfail#033[39m#033[22m#033[49m: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
Jan 1 00:36:57 ip-172-30-2-135 web: An unhandled exception has occurred while executing the request.
Jan 1 00:36:57 ip-172-30-2-135 web: System.NullReferenceException: Object reference not set to an instance of an object.
Jan 1 00:36:57 ip-172-30-2-135 web: at Microsoft.Extensions.DependencyInjection.IdentityServerBuilderConfigurationExtensions.<>c.b__10_2(IServiceProvider sp)
Jan 1 00:36:57 ip-172-30-2-135 web: at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
Jan 1 00:36:57 ip-172-30-2-135 web: at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
有人 运行 以前参与过这个吗?这是特定于部署到 AWS beanstalk 的东西。如果我删除 UseIdentityServer()
调用,应用程序会在 AWS Beanstalk 中发布并且 运行 正常。如果这有所不同,我将发布到 Linux beantalk。部署到 Linux 时,必须使用 IdentityServer 进行不同的配置,或者可能需要使用 AWS Beanstalk 进行特定配置。
当 运行 在我的开发机器上本地运行时,它在 Windows 10 以防有帮助。
编辑:添加 ConfigureServices() 方法
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BarristerContext>(options =>
options.UseNpgsql(
Configuration["Data:DefaultConnection:ConnectionString"]));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<BarristerContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest)
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
});
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
// using Microsoft.AspNetCore.Identity.UI.Services;
services.AddSingleton<IEmailSender, EmailSender>();
services.AddIdentityServer(options =>
{
options.UserInteraction = new UserInteractionOptions()
{
LogoutUrl = "/Identity/account/logout",
LoginUrl = "/Identity/account/login",
LoginReturnUrlParameter = "returnUrl"
};
}).AddApiAuthorization<ApplicationUser, BarristerContext>();
services.AddAuthentication().AddIdentityServerJwt();
services.AddControllersWithViews();
services.AddRazorPages();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
//services.AddDatabaseDeveloperPageExceptionFilter();
}
我还要注意,我在此部署上的目标是 .Net 5,根据 AWS,只要我在通过 AWS 发布时 select“构建自包含部署包”,它应该可以正常工作Visual Studio.
的工具包
https://aws.amazon.com/blogs/developer/aws-elastic-beanstalk-adds-net-core-on-linux-platform/
我的本地主机与导致 Beanstalk 错误的 AWS Beanstalk 之间的区别是 Nginx 代理。我必须通过在 Startup.cs.
的 ConfigureServices() 方法中添加以下中间件来解决这个问题
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
这是由于:
当通过 HTTP 代理 HTTPS 请求时,原始方案 (HTTPS) 丢失,必须在 header 中转发。
因为应用从代理接收请求而不是它在 Internet 或公司网络上的真实来源,所以原始客户端 IP 地址也必须在 header 中转发。
以下文章提供了更多详细信息:https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-5.0
我有一个 asp.net 核心应用程序,其 React 前端使用 IdentityServer。它是在 Visual Studio 2019 年使用脚手架模板创建的。该应用程序在本地运行良好,但在我部署到 AWS beanstalk 时失败。它失败的代码行在我的 Startup.cs
的 Configure
方法中。 app.UseIdentityServer()
.
在 UseIdentityServer()
的某处有一个我看不到的空引用异常,在我的开发机器上进行本地测试时我无法重现。
这是我在 Startup.cs
中的 Configure()
方法:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
//app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
//app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
//spa.UseReactDevelopmentServer(npmScript: "start"); // Starts CRA automatically
spa.UseProxyToSpaDevelopmentServer("http://localhost:3000"); // Must manually start CRA (yarn start)
}
});
}
}
我在检查 AWS beantalk 日志时遇到如下错误:
Jan 1 00:36:57 ip-172-30-2-135 web: #033[41m#033[30mfail#033[39m#033[22m#033[49m: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1] Jan 1 00:36:57 ip-172-30-2-135 web: An unhandled exception has occurred while executing the request. Jan 1 00:36:57 ip-172-30-2-135 web: System.NullReferenceException: Object reference not set to an instance of an object. Jan 1 00:36:57 ip-172-30-2-135 web: at Microsoft.Extensions.DependencyInjection.IdentityServerBuilderConfigurationExtensions.<>c.b__10_2(IServiceProvider sp) Jan 1 00:36:57 ip-172-30-2-135 web: at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context) Jan 1 00:36:57 ip-172-30-2-135 web: at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
有人 运行 以前参与过这个吗?这是特定于部署到 AWS beanstalk 的东西。如果我删除 UseIdentityServer()
调用,应用程序会在 AWS Beanstalk 中发布并且 运行 正常。如果这有所不同,我将发布到 Linux beantalk。部署到 Linux 时,必须使用 IdentityServer 进行不同的配置,或者可能需要使用 AWS Beanstalk 进行特定配置。
当 运行 在我的开发机器上本地运行时,它在 Windows 10 以防有帮助。
编辑:添加 ConfigureServices() 方法
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<BarristerContext>(options =>
options.UseNpgsql(
Configuration["Data:DefaultConnection:ConnectionString"]));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<BarristerContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest)
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
});
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
// using Microsoft.AspNetCore.Identity.UI.Services;
services.AddSingleton<IEmailSender, EmailSender>();
services.AddIdentityServer(options =>
{
options.UserInteraction = new UserInteractionOptions()
{
LogoutUrl = "/Identity/account/logout",
LoginUrl = "/Identity/account/login",
LoginReturnUrlParameter = "returnUrl"
};
}).AddApiAuthorization<ApplicationUser, BarristerContext>();
services.AddAuthentication().AddIdentityServerJwt();
services.AddControllersWithViews();
services.AddRazorPages();
// In production, the React files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
//services.AddDatabaseDeveloperPageExceptionFilter();
}
我还要注意,我在此部署上的目标是 .Net 5,根据 AWS,只要我在通过 AWS 发布时 select“构建自包含部署包”,它应该可以正常工作Visual Studio.
的工具包https://aws.amazon.com/blogs/developer/aws-elastic-beanstalk-adds-net-core-on-linux-platform/
我的本地主机与导致 Beanstalk 错误的 AWS Beanstalk 之间的区别是 Nginx 代理。我必须通过在 Startup.cs.
的 ConfigureServices() 方法中添加以下中间件来解决这个问题services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
这是由于:
当通过 HTTP 代理 HTTPS 请求时,原始方案 (HTTPS) 丢失,必须在 header 中转发。
因为应用从代理接收请求而不是它在 Internet 或公司网络上的真实来源,所以原始客户端 IP 地址也必须在 header 中转发。
以下文章提供了更多详细信息:https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-5.0