如何使 Asp.NET 核心 MVC 应用在授权重定向时使用外部 URL?

How to make Asp.NET Core MVC app use external urls on Authorize redirection?

我正在寻找问题标题中所述问题的解决方案。 更准确地说 - 我正在 运行 测试应用程序 (asp.net core/mvc) 并使用 https://ngrok.com 将其隧道化以使其可访问 world-wide。我为此使用的命令是:

ngrok.exe http -host-header=rewrite localhost:62274

"ngrok.exe http"用于初始化ngrok,“-host-header=rewrite localhost:62274”改变header允许app执行(因为IIS检查header 并阻止任何其他)。

我 运行 遇到的问题是授权失败后(访客试图访问受限页面)[Authorize] 指向内部链接(例如“http://localhost:62274/Account/Login").这是的意图。
应用程序视图提供的所有链接都正常工作(它们使用 ngrok 提供的地址前缀)。我必须修复 Login/Register 的 returnUrl 参数,但它们现在工作正常。

我已经为该问题搜索了 2 天的答案。如前所述,这是我正在制作的测试应用程序,用于学习 .net Core 中的编程。限制是我不想写我自己的授权 - 这很容易因为我没有经验,它需要不断的安全更新并且没有必要重新发明轮子,对吧?

问题发生在:

[Authorize("Admin")]
public async Task<IActionResult> DeleteDItem(int? id)

而不是重定向到:http://<8_random_characters>.ngrok.io/Account/Login 它指向:http://localhost:62274/Account/Login

更多细节(这是我在这里写的第一个问题,所以我希望它有点合适):
- 这是一个 ASP.NET 核心 Web 应用程序,使用 MVS2015 的默认 "Individual User Authentication"、
- 相关 project.json 信息:

"dependencies": {  
  "BundlerMinifier.Core": "2.1.258",  
  "Microsoft.ApplicationInsights.AspNetCore": "1.0.0",  
  "Microsoft.AspNet.Authentication.Google": "1.0.0-rc1-final",  
  "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0",  
  "Microsoft.AspNetCore.Authentication.Facebook": "1.0.0",  
  "Microsoft.AspNetCore.Authentication.Google": "1.0.0",  
  "Microsoft.AspNetCore.Authorization": "1.0.0",  
  "Microsoft.AspNetCore.Diagnostics": "1.0.0",  
  "Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore": "1.0.0",  
  "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",  
  ...
  "Npgsql.EntityFrameworkCore.PostgreSQL": "1.0.0"

- Startup.cs的相关部分:

public void ConfigureServices(IServiceCollection services)
{
  services.AddAuthorization(options =>
  {
    options.AddPolicy("Admin", policy => 
                               policy.RequireAuthenticatedUser());                
  });
  services.AddIdentity<ApplicationUser, IdentityRole>()
          .AddEntityFrameworkStores<ApplicationDbContext>()
          .AddDefaultTokenProviders();
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env,
                      ILoggerFactory loggerFactory)
{
  app.UseIdentity();
}

更新 1。(原始问题请阅读下文)。

解决方案 1:使其与 IIS 一起工作 现在我让它与 IIS 一起工作。 (不适用于 IIS Express)。

  1. 我在本地 iis 上的特定端口上发布站点。

  2. 我使用了以下命令。

ngrok.exe http 8042 ( what ever port you choose)

确保您使用了您未使用的上述命令。在您的命令中,您使用了特殊的 -host-header=rewrite 选项。现在,当请求从 iis 移动到 Kerstel 服务器时,此选项将重写主机值。该主机值用于构建登录 url 并产生问题。

ngrok.exe http -host-header=rewrite localhost:62274

解决方案 2:使其与 IIS Express 一起工作。

你仍然必须使用我用过的相同命令而不是你的。

ngrok.exe http yourportnumber

现在要使其与 IIS Express 一起使用,您必须转到解决方案根文件夹。你会在那里找到 .vs 文件夹。 (它是隐藏的)。所以你也必须启用查看隐藏文件夹。

现在转到 .vs -> 配置 -> applicationhost.config

打开此文件并搜索网站部分,它看起来像这样。 (我已经删除了很多代码,因为你必须更新绑定信息)

<sites>          
            <site name="WebApplication2" id="4">                
                <bindings>
                    <binding protocol="http" bindingInformation="*:12619:localhost" />
                </bindings>
            </site>           
        </sites>

将其替换为(请参阅我将 localhost 替换为 *)

<sites>          
            <site name="WebApplication2" id="4">                
                <bindings>
                    <binding protocol="http" bindingInformation="*:12619:*" />
                </bindings>
            </site>           
        </sites>

注意: 1. 如果 VS 已经处于调试模式,则停止它并重新启动。它现在应该工作了。因为它对我有用。

  1. 之前在评论中我说它适用于 MVC5,但仅当您使用默认身份验证时才有效。如果您使用 Owin 管道并在 ngrok.exe 开关中使用 -host-header 开关,那么您将得到同样的错误。

其实我想把这个放在评论里,但是它有点长,所以我放在了这里。这就是为什么会这样。

  1. 真正的原因是无法正确构建 url。 https://github.com/aspnet/Security/blob/dev/src/Microsoft.AspNetCore.Authentication/AuthenticationHandler.cs

在上面的 cs 文件中,BuildRedirectUri 是为其构建登录 uri。

  1. 上面的第二个原因,当你使用 ngrok 并且你遵守 Request.Host 总是 localhost:<> 这会产生问题。 (这是罪魁祸首)

  2. 我使用主机文件测试了其他方式,它工作正常。 Request.Host 显示正确的主机名。

根据我的意见和旧版本的 MVC5,它应该保留提供的 ngrok 主机名而不是本地主机。我认为真正的问题是当请求从 IIS 转移到 Kestrel 时。