我面临以下问题。我有一个ASP Net Core 2 Web应用程序,我想部署到Azure。应用程序身份验证与Azure Active Directory集成,因此当我尝试登录时,会发生以下请求:
GET https://login.microsoftonline.com/ecf3f643-27e5-4aa7-9d56-fd350e1e9c37/oauth2/authorize?client_id=20a2bcb5-0433-4bb4-bba3-d7dc4c533e85&redirect_uri=http://myapplication.mydomain.com/account/signin [...] 200 OK
POST http://myapplication.mydomain.com/account/signin 301 Redirect --> https://myapplication.mydomain.com/account/signin
GET https://myapplication.mydomain.com/account/signin 500 Internal Server Error
第一个GET是正常的Azure Active Directory登录请求。 请注意,redirect_uri
参数包含协议http 。
第二个请求是重定向到redirect_uri
,一个带有一些参数的POST。由于我已将Azure配置为仅允许HTTPS流量,因此IIS使用HTTPS重定向到相同的URL。这是第三个请求。请注意,第三个请求是GET请求,因为HTTP redirection is always a GET request POST请求的所有参数都会丢失,并且身份验证失败会在后端发出HTTP 500错误。
我尝试手动将redirect_uri
参数中的协议手动更改为HTTPS,可以正常工作。所以,我唯一需要的是让ASP Net Core意识到协议是HTTPS 。
怎么办?我没有明确的答案,在互联网上搜索了大量的页面。
注意:redirect_uri
由Kestrel设置。由于Azure App Service将IIS放在我的Kestrel前面并在那里进行SSL终止,因此Kestrel和我的应用程序不知道协议是HTTPS,因此在重定向uri中使用HTTP。
更新1
按照@Bruce的建议,我尝试了示例here,克隆了存储库并按照其中的说明配置了应用程序和AD,我能够重现错误。
重定向URI继续使用http
协议。如果我只在AD应用配置中添加https
端点作为回复网址,则会收到错误The reply address 'http://testloginad.azurewebsites.net/signin-oidc' does not match the reply addresses configured for the application
。如果我将http
协议端点添加为回复URL,则会收到如下所示的HTTP 500错误:
System.Exception: Correlation failed.
at Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler`1.<HandleRequestAsync>d__12.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.<Invoke>d__6.MoveNext()
我仍然在想问题与Kestrel有关,不知道通过HTTPS 正在进行连接,但我不知道如何将信息传达给它。
更新2
我使用的Azure网络应用程序的配置:
在web.config
文件中,我修改了以下行,如下所示:
<aspNetCore processPath="dotnet" arguments="./WebApp-OpenIDConnect-DotNet.dll" stdoutLogEnabled="false" stdoutLogFile="./stdout.log" />
基本上我提出斜杠而不是反斜杠,以避免Linux路径出现问题。
使用默认设置配置其他所有内容。
更新3 根据{{3}}的要求,我在这里添加了服务器响应的标题(为了简洁起见,我只包括我认为相关的标题,如果你想看到任何其他标题,请随时让我添加它):
GET https://login.microsoftonline.com/ecf...
):
Microsoft-IIS/10.0
ESTSAUTHPERSISTENT=AQAFCCEADDB…sts; path=/; secure; HttpOnly
max-age=31536000; includeSubDomains
POST http://testloginad.azurewebsites.net/signin-oidc
):
https://testloginad.azurewebsites.net/signin-oidc
Microsoft-IIS/10.0
GET https://testloginad.azurewebsites.net/signin-oidc
):
Kestrel
任何请求中都不会显示x-forwarded-proto
标头。
请注意,问题的根源可能在第二个请求的重定向中,即将HTTP POST重定向到HTTPS GET。该重定向不应该发生,因为POST应该首先通过HTTPS请求,但是由于第一个请求的redirect_uri中的http协议错误而没有发生。
更新4
我已经确认只有选择的服务计划是Linux服务计划才会出现此问题。如果服务计划是Windows服务计划(使用与UPDATE 1示例完全相同的代码和配置),则根本不会发生此问题。对于问题,这可能是一种解决方法,但不是解决方案。 Linux应用程序服务似乎存在缺陷。
答案 0 :(得分:1)
通过咨询以下链接:
对配置进行3处更改,我就可以在Linux App Plan上进行所有工作。
第1步:配置 ForwardedHeadersOptions
services.Configure<ForwardedHeadersOptions>(options =>
{
options.RequireHeaderSymmetry = false;
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
// TODO : it's a bit unsafe to allow all Networks and Proxies...
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
步骤2:public void Configure(IApplicationBuilder app, IHostingEnvironment env)
方法中的 UseForwardedHeaders
app.UseForwardedHeaders();
第3步:仅将 UseHttpsRedirection 用于生产
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
// Forward http to https (only needed for local development because the Azure Linux App Service already enforces https)
app.UseHttpsRedirection();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
答案 1 :(得分:1)
我自己遇到了问题。我深入研究了Microsoft的Microsoft.AspNetCore.Authentication,并了解了他们如何构造重定向网址:
protected string BuildRedirectUri(string targetPath)
=> Request.Scheme + "://" + Request.Host + OriginalPathBase + targetPath;
由于Web应用程序已经强制执行HTTPS,因此可以使用Startup.cs中的以下代码解决该问题
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedProto
});
您只需添加以下参考:
using Microsoft.AspNetCore.HttpOverrides;
答案 2 :(得分:0)
我面临以下问题。我有一个ASP Net Core 2 Web应用程序,我想部署到Azure。应用程序身份验证与Azure Active Directory集成。
由于您没有提到您是如何将AAD身份验证集成到Web应用程序中的。而且,我已经检查过了
通过http://analytics.lantek360.com
或https://analytics.lantek360.com
访问您的应用时,redirect_uri
查询字符串将相同:http://analytics.lantek360.com/account/signin
。您可以提供更多详细信息(例如,您是如何构建授权请求)以缩小此问题。
由于我已将Azure配置为仅允许HTTPS流量
“仅HTTPS”设置使用URL重写规则将HTTP重定向到HTTPS。详细信息,您可以关注How to make an Azure App Service HTTPS only。
根据您的要求,我假设您可以手动使用middileware Microsoft.AspNetCore.Authentication.OpenIdConnect将Azure AD集成到.Net Core Web应用程序中。对于这种方法,您可以按照以下教程进行操作:
Integrating Azure AD (v1.0 endpoint) into an ASP.NET Core web app
Integrating Azure AD (v2.0 endpoint) into an ASP.NET Core web app
注意:强>
OpenID Connect的redirect_uri
看起来像http(s)://<your-appname>.azurewebsites.net/signin-oidc
。由于您只需要Https,因此您只需为您的AAD应用添加重定向URI(https://{your-appname}.azurewebsites.net/signin-oidc
)。
此外,您还可以利用App Service Authentication / Authorization启用AAD身份验证,而无需更改Web应用程序中的代码。详细信息,您可以在Azure门户中关注Configure your App Service app to use Azure Active Directory login。
答案 3 :(得分:0)
解决此问题的方法如下:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// ...
/***
* Forwarded Headers were required for nginx at some point.
* https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.1#nginx-configuration
***/
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
RequireHeaderSymmetry = false,
ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedFor
});
// ...
}
不幸的是,我去看了一下如何修复它的代码,但是我不记得为什么会这样:)(我留下的评论也没有帮助)
希望有帮助。
答案 4 :(得分:0)
通过结合以下ForwardedHeadersOptions配置使其工作:
const books = [
{"book": "Typescript 1", "year": "2015", "units": 1000},
{"book": "Javascript 1", "year": "2015", "units": 2000},
{"book": "Typescript 1", "year": "2016", "units": 6000}
];
const merged = Object.values(books.reduce((acc, { book, year, units }) => {
acc[book] = acc[book] || { book, series: [] };
acc[book].series.push({ year, units });
return acc;
}, {}));
console.log(merged);
答案 5 :(得分:0)
这是来自ASP.NET身份和IdentityServer专家 Chris Ross (又名 Tratcher )的link to the recommended solution。
您需要的代码是
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
// Only loopback proxies are allowed by default. Clear that restriction because forwarders are
// being enabled by explicit configuration.
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
app.UseForwardedHeaders();
它似乎仅适用于.NET Core v2.x,并且已在3.0中修复。