Microsoft.AspNetCore.Authentication.OpenIdConnect /oauth2/authorize 端点形式 - redirect_uri 错误
Microsoft.AspNetCore.Authentication.OpenIdConnect /oauth2/authorize endpoint form - redirect_uri error
我有一个应用程序(.NET 5.0 ASP Net Core)应用程序,我正在尝试将其部署到 AWS Amazon Linux 2 服务器。看起来部署的所有方面都很好,除了 AWS Congnito 和 Microsoft.AspNetCore.Authentication.OpenIdConnect 的授权。在 dev/local 中一切正常,问题只会在产品部署中出现。
问题表现为“请求的页面遇到错误”。尝试登录时在 Hosted UI 中的 https://auth.<mydomain>.com/error?error=redirect_mismatch&client_id=<myclientid>
。我已经确认并再次确认回调 URL(s) 设置正确:https://sub.domain.com/signin-oidc, https://localhost:5001/signin-oidc
.
我的应用程序位于 http://localhost:5000 上 运行,位于 apache 反向代理后面。我怀疑 Apache 和 Kestrel 之间路径的非 HTTPS 部分是问题所在。
我注意到 Microsoft.AspNetCore.Authentication.OpenIdConnect 在 redirect_uri 值中缺少 https,它创建为它调用的 /oauth2/authorize 端点的一部分。
这是我在 Dev 中看到的(没有问题):
这是我在部署时看到的,注意 redirect_uri 是 http:
在应用程序客户端设置中,我无法将 signin-oidc 端点设置为使用 HTTP。
我的配置服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.ResponseType = "code";
options.ResponseType = Configuration["Authentication:Cognito:ResponseType"];
options.MetadataAddress = Configuration["Authentication:Cognito:MetadataAddress"];
options.ClientId = Configuration["Authentication:Cognito:ClientId"];
options.TokenValidationParameters = new TokenValidationParameters
{
RoleClaimType = "cognito:groups"
};
options.Events = new OpenIdConnectEvents
{
OnTicketReceived = e =>
{
e.ReturnUri = string.Format("/Home/CheckProfile?url={0}", HttpUtility.UrlEncode(e.ReturnUri));
return Task.CompletedTask;
}
};
});
}
那么,为什么 Microsoft.AspNetCore.Authentication.OpenIdConnect 在生成 /oauth2/authorize 端点的 redirect_uri 值时使用 HTTP。那是我需要在某处调整的东西吗?而且,这似乎是导致我的整体 https://auth.<mydomain>.com/error?error=redirect_mismatch&client_id=<myclientid>
问题的核心问题吗?
这里的核心问题是反向代理; Kestrel 运行 落后于 Apache。虽然我在过去几年中经常使用此设置(与 certbot),但我以前没有将它与 OIDC 身份验证方案一起使用。问题是 apache 的 https 终止以及 Apache 和 Kestrel 之间的 http 传输。 OIDC 身份验证方案(在我的例子中由 AWS Cognito 支持)需要端到端 https。
“作为 /oauth2/authorize 端点的一部分创建的 redirect_uri 值中缺少 https”只是我发现的众多问题中的第一个。我想出了一个解决这个问题的方法:
.AddOpenIdConnect(options =>
{
...
options.Events = new OpenIdConnectEvents
{
...
OnRedirectToIdentityProvider = async n =>
{
n.ProtocolMessage.RedirectUri = n.ProtocolMessage.RedirectUri.Replace("http://", "https://");
await Task.FromResult(0);
}
};
});
但这只解决了更改 redirect_uri 原型的狭隘问题;然后出现其他 cookie SameSite=None/Secure/http 问题。
至此,我已经成功地在 80 和 443 上直接暴露了 Kestrel。我意识到这是否是一个谨慎的想法值得商榷,但它目前和今天(2021 年夏季在 .NET 5.0 上)对我有用) 似乎 Kestrel 已经成熟到不再是“只在开发中这样做!”的地步。工具。
我发现这两篇文章都非常有帮助:
https://swimburger.net/blog/dotnet/how-to-run-aspnet-core-as-a-service-on-linux
https://thecodeblogger.com/2021/05/07/certificates-and-limits-for-asp-net-core-kestrel-web-server/
更好的答案。虽然“Kestrel 暴露于世界”的答案有效,但我最终弄清楚了如何使反向代理与 Cognito 一起工作。
在反向代理中,我最终设置了“'https' env=HTTPS”,如下所示:
<VirtualHost *:*>
RequestHeader set "X-Forwarded-Proto" 'https' env=HTTPS
</VirtualHost>
我还重新安排了我的 Prod Configure(...) 如下:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseForwardedHeaders();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseForwardedHeaders();
app.Use((ctx, next) =>
{
ctx.Request.Host = new HostString("sub.domain.com");
ctx.Request.Scheme = "https";
return next();
});
app.UseHsts();
}
我有一个应用程序(.NET 5.0 ASP Net Core)应用程序,我正在尝试将其部署到 AWS Amazon Linux 2 服务器。看起来部署的所有方面都很好,除了 AWS Congnito 和 Microsoft.AspNetCore.Authentication.OpenIdConnect 的授权。在 dev/local 中一切正常,问题只会在产品部署中出现。
问题表现为“请求的页面遇到错误”。尝试登录时在 Hosted UI 中的 https://auth.<mydomain>.com/error?error=redirect_mismatch&client_id=<myclientid>
。我已经确认并再次确认回调 URL(s) 设置正确:https://sub.domain.com/signin-oidc, https://localhost:5001/signin-oidc
.
我的应用程序位于 http://localhost:5000 上 运行,位于 apache 反向代理后面。我怀疑 Apache 和 Kestrel 之间路径的非 HTTPS 部分是问题所在。
我注意到 Microsoft.AspNetCore.Authentication.OpenIdConnect 在 redirect_uri 值中缺少 https,它创建为它调用的 /oauth2/authorize 端点的一部分。
这是我在 Dev 中看到的(没有问题):
这是我在部署时看到的,注意 redirect_uri 是 http:
在应用程序客户端设置中,我无法将 signin-oidc 端点设置为使用 HTTP。
我的配置服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.ResponseType = "code";
options.ResponseType = Configuration["Authentication:Cognito:ResponseType"];
options.MetadataAddress = Configuration["Authentication:Cognito:MetadataAddress"];
options.ClientId = Configuration["Authentication:Cognito:ClientId"];
options.TokenValidationParameters = new TokenValidationParameters
{
RoleClaimType = "cognito:groups"
};
options.Events = new OpenIdConnectEvents
{
OnTicketReceived = e =>
{
e.ReturnUri = string.Format("/Home/CheckProfile?url={0}", HttpUtility.UrlEncode(e.ReturnUri));
return Task.CompletedTask;
}
};
});
}
那么,为什么 Microsoft.AspNetCore.Authentication.OpenIdConnect 在生成 /oauth2/authorize 端点的 redirect_uri 值时使用 HTTP。那是我需要在某处调整的东西吗?而且,这似乎是导致我的整体 https://auth.<mydomain>.com/error?error=redirect_mismatch&client_id=<myclientid>
问题的核心问题吗?
这里的核心问题是反向代理; Kestrel 运行 落后于 Apache。虽然我在过去几年中经常使用此设置(与 certbot),但我以前没有将它与 OIDC 身份验证方案一起使用。问题是 apache 的 https 终止以及 Apache 和 Kestrel 之间的 http 传输。 OIDC 身份验证方案(在我的例子中由 AWS Cognito 支持)需要端到端 https。
“作为 /oauth2/authorize 端点的一部分创建的 redirect_uri 值中缺少 https”只是我发现的众多问题中的第一个。我想出了一个解决这个问题的方法:
.AddOpenIdConnect(options =>
{
...
options.Events = new OpenIdConnectEvents
{
...
OnRedirectToIdentityProvider = async n =>
{
n.ProtocolMessage.RedirectUri = n.ProtocolMessage.RedirectUri.Replace("http://", "https://");
await Task.FromResult(0);
}
};
});
但这只解决了更改 redirect_uri 原型的狭隘问题;然后出现其他 cookie SameSite=None/Secure/http 问题。
至此,我已经成功地在 80 和 443 上直接暴露了 Kestrel。我意识到这是否是一个谨慎的想法值得商榷,但它目前和今天(2021 年夏季在 .NET 5.0 上)对我有用) 似乎 Kestrel 已经成熟到不再是“只在开发中这样做!”的地步。工具。
我发现这两篇文章都非常有帮助:
https://swimburger.net/blog/dotnet/how-to-run-aspnet-core-as-a-service-on-linux
https://thecodeblogger.com/2021/05/07/certificates-and-limits-for-asp-net-core-kestrel-web-server/
更好的答案。虽然“Kestrel 暴露于世界”的答案有效,但我最终弄清楚了如何使反向代理与 Cognito 一起工作。
在反向代理中,我最终设置了“'https' env=HTTPS”,如下所示:
<VirtualHost *:*>
RequestHeader set "X-Forwarded-Proto" 'https' env=HTTPS
</VirtualHost>
我还重新安排了我的 Prod Configure(...) 如下:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseForwardedHeaders();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseForwardedHeaders();
app.Use((ctx, next) =>
{
ctx.Request.Host = new HostString("sub.domain.com");
ctx.Request.Scheme = "https";
return next();
});
app.UseHsts();
}