ASP.NET 5 - Azure AD 身份验证 - 运行 使用 DNX web 命令时重定向循环 - secrets.json

ASP.NET 5 - Azure AD Authentication - Redirect Loop when run with DNX web command - secrets.json

我创建了一个新的 ASP.NET 5 MVC 6 应用程序(工作和学校帐户身份验证),并且在转到 http://localhost:5000/Account/Signin 等任何经过身份验证的页面时出现重定向循环。如果我在命令提示符下发布应用程序和 运行 web.cmd (DNX),就会发生这种情况。

我所知道的是,如果我将托管环境设置为开发,问题在我的开发机器上得到解决,但是将具有相同“--ASPNET_ENV 开发”设置的已发布应用程序复制到任何其他机器会得到重定向问题。

  "commands": {
    "web": "Microsoft.AspNet.Server.Kestrel --ASPNET_ENV Development"
  },

我可以始终如一地重现这一点。关闭身份验证也可以解决问题,但对我没有帮助。发布到 Azure 也有效。

首先,我想知道为什么将托管环境设置为开发可以修复我的开发机器上的重定向问题,其次,我想知道为什么它在任何其他机器上都不起作用。在另一台机器上的 IIS 中使用 Hosing 也会出现重定向循环问题,但它在我的开发机器上的 IIS Express 中工作正常。

这很容易重现。在 VS 2015 中,创建一个新的 ASP.NET 5 网络应用程序,选择(工作和学校帐户身份验证)并发布选择文件系统。转到发布目录和 运行 web.cmd。如果它显示 Hosting Environment Production,您可能会遇到问题。将环境更改为开发将解决此问题,但即使将托管环境设置为开发,将已发布的应用程序复制到另一台机器也会出现相同的重定向问题。

更新: 我现在知道 Azure AD 身份验证的设置,例如Authentication:AzureAd:AADInstance 在 secrets.json 文件 %APPDATA%\microsoft\UserSecrets\\secrets.json 中。我可以使用命令行用户机密列表读取它们。此 secrets.json 文件仅在环境设置为 Development 时加载,这回答了我的第一个问题:

if (env.IsDevelopment())
        {
            // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
            builder.AddUserSecrets();
        }

secrets.json 文件也不是部署包的一部分,所以这回答了我的第二个问题,即为什么当我将包复制到另一台机器时它不起作用。

我知道需要弄清楚 secrets.json 是如何在生产环境中使用的。

Startup.cs 应要求在此:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Authentication.Cookies;
using Microsoft.AspNet.Authentication.OpenIdConnect;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace TestAzureAD
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            // Set up configuration sources.
            var builder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

            if (env.IsDevelopment())
            {
                // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
                builder.AddUserSecrets();
            }
            builder.AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; set; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            if (env.IsDevelopment())
            {
                app.UseBrowserLink();
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseIISPlatformHandler();

            app.UseStaticFiles();

            app.UseCookieAuthentication(options =>
            {
                options.AutomaticAuthenticate = true;
            });

            app.UseOpenIdConnectAuthentication(options =>
            {
                options.AutomaticChallenge = true;
                options.ClientId = Configuration["Authentication:AzureAd:ClientId"];
                options.Authority = Configuration["Authentication:AzureAd:AADInstance"] + Configuration["Authentication:AzureAd:TenantId"];
                options.PostLogoutRedirectUri = Configuration["Authentication:AzureAd:PostLogoutRedirectUri"];
                options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            });

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }

        // Entry point for the application.
        public static void Main(string[] args) => WebApplication.Run<Startup>(args);
    }
}

Azure AD 身份验证设置,例如Authentication:AzureAd:AADInstance 在 secrets.json 文件 %APPDATA%\microsoft\UserSecrets\secrets.json 中。这也适用于其他身份验证类型。

密文API可用于管理密文。 https://github.com/aspnet/Home/wiki/DNX-Secret-Configuration

dnu commands install Microsoft.Extensions.SecretManager 
user-secret list

在dev机器上开发,可以使用secrets.json文件,但在其他机器上,没有secrets.json文件,需要从appsettings.json读取设置和 appsettings.[environmentname].json。将 secrets.json 设置复制到 appsettings.json 解决了这个问题,因为 azure authenication 现在知道去哪里并且不再循环重定向到自身。

启动代码显示设置是从 appsettings.json 和 appsettings.[environmentname].json 以及开发环境中的 secrets.json 读取的。

   public Startup(IHostingEnvironment env)
    {
        // Set up configuration sources.
        var builder = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

        if (env.IsDevelopment())
        {
            // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
            builder.AddUserSecrets();
        }
        builder.AddEnvironmentVariables();
        Configuration = builder.Build();
    }