![](/img/trans.png)
[英]Error Deploying ASP.NET Core Web Application + ReactJS to Azure
[英]Hosting asp.net core + ReactJS web app with SSL containing multiple CN or domain names is causing invalid issuer error
我在托管使用 asp.net core 3.1 和 React 构建的 Web 应用程序时遇到以下问题。
我们为 React 使用了默认的 Visual Studio 模板。 ASP.NET Identity 用于身份验证和授权。
只要我们使用为单个域或 CN 颁发的 SSL 证书托管网站,身份验证和授权就会按预期工作。 (例如example.com)
如果我们使用带有多个 CN(例如 example.com、sub1.example.com、sub2.example.com)的 SSL 托管他的网站,则它适用于任何一个域。 对于其余域,我们得到以下行为:
登录按预期工作。 /connect/token 路径发出有效的令牌。 登录后,当我们尝试调用任何 api(所有 api 都托管在 /api 路由下)时,我们会收到 401 未经授权的错误。 标题中的错误描述:
WWW-Authenticate: Bearer error="invalid_token", error_description="颁发者 ' https://sub1.example.com ' 无效"。
我还尝试在 jwt.io 上解析发布的令牌。 iss 字段(颁发者)是https://sub1.example.com ,它与错误描述完全匹配。 我无法理解为什么身份引擎拒绝识别为其颁发令牌的发行者。
这是来自 Startup.cs 的相关片段
public void ConfigureServices(IServiceCollection services)
{
services.AddIdentityServer()
.AddApiAuthorization<ApplicationUser, ApplicationDbContext>();
services.AddAuthentication()
.AddIdentityServerJwt();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();
}
有任何想法吗?
新的 .Net(.net 核心)是高度可配置和模块化的。 通常扩展方法采用一个委托,我们可以使用它来配置选项。 但是, AddIdentityServerJwt
方法不遵循该约定。
我注意到很久以前,有一个叫做财产ValidIssuers
在TokenValidationParameters
可与AddJwtBearer扩展方法来配置。 但是, AddIdentityServerJwt
扩展方法不接受任何选项委托作为参数。
事实证明,有一种特殊的方式来配置选项。
services.AddAuthentication()
.AddIdentityServerJwt();
services.Configure<JwtBearerOptions>(IdentityServerJwtConstants.IdentityServerJwtBearerScheme, options =>
{
options.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters()
{
ValidIssuers = new string[] { "https://sub1.example.com", "https://sub2.example.com", "https://sub3.example.com" }
};
});
添加了此代码并解决了问题。 配置也可以移动到 appsettings.json。
这可能是因为从一个 CN 上的 IdentityServer4 实例接收令牌,并尝试使用另一个 CN 向 IdentityServer4 发出请求来验证它。 拒绝令牌的 IdentityServer 组件是 TokenValidator 的ValidateJwtAsync方法。 此方法将在发行人进入JwtSecurityTokenHandler的ValidateToken作为一个属性TokenValidationParameters 。 颁发者是从在“AddIdentityServer”扩展方法中的IdentityServerOptions上配置的颁发者中检索的,或者是从请求动态生成的。
我可以想到一种解决验证问题的方法,那就是使用传递给AddIdentityServer的委托在 IdentityServerOptions 上设置颁发者。 这将导致为所有发行的令牌设置相同的发行者,而不管它是从哪个 CN 访问的。 这将使 IdentityServer 成为颁发者信息的单一真实来源,并允许 IdentityServer 在令牌进入验证时知道要验证哪个颁发者。
其他试图维护发行者的解决方案受到 TokenValidator 是一个内部类的严重限制,该类不能被继承,并且很容易被替换为将针对有效发行者列表进行验证的实现。 此外,配置为具有颁发者 uri 的 IdentityServerOptions 注册为单例,并且不能更改其值。 可以设计其他人为的实现,例如尝试使用中间件动态更改 HttpContext 上的主机值(我不确定是否可能,因为我从未尝试过),但不建议任何违反 IdentityServer4 设计决策的内容。
请检查网址 http://{url}/.well-known/openid-configuration
这个网址应该是真的
以下代码适用于不同的领域。 验证启动
services.AddIdentityServer(options =>
{
options.IssuerUri = Configuration["ServerSettings:Authority"].ToString();
options.PublicOrigin = Configuration["ServerSettings:Authority"].ToString();
})
.AddDeveloperSigningCredential()
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryClients(Config.GetClients())
.AddProfileService<ProfileService>();
api启动
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
{
options.Authority = Configuration["ServerSettings:Authority"].ToString(); //"http://localhost:31864";
options.RequireHttpsMetadata = false;
options.ApiName = "api";
});
在同一个域中工作,但如果域不同,则应指定此项
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.