【问题标题】:Can I use HTTP instead of HTTPS to host MVC client to work with IdentityServer?我可以使用 HTTP 而不是 HTTPS 来托管 MVC 客户端以使用 IdentityServer 吗?
【发布时间】:2021-02-04 20:25:23
【问题描述】:

我的快速入门程序在我的本地测试环境中运行:一个 MVC 客户端通过 IdentityServer 访问 API。这一切都是使用 HTTPS 和self-host (Kestrel) 设置的。我想知道的是 - 在使用 IdentityServer 时,我可以在 HTTP 而不是 HTTPS 中托管 MVC 吗?如果我将所有各方更改为使用 HTTP 或仅使用 MVC,而将其余部分使用 HTTPS,这似乎并不重要,只要我将 MVC 从 https://localhost:5009 更改为 http://localhost:5008(在几个地方),应用程序就会失败并显示错误"invalid redirect uri".
我是否遗漏了什么,或者这只是不允许的?

【问题讨论】:

    标签: asp.net-core-mvc identityserver4


    【解决方案1】:

    您可以在开发过程中很好地通过 HTTP 运行,但在生产中您应该始终尝试使用 HTTPS。

    您得到的错误是因为 IdentityServer 中客户端定义中的 RedirectURLs 与您客户端的 url 不匹配:

    RedirectUris =
    {
        "https://localhost:5001/...."
    },
    

    如果您想在定义 OpenIDConnect 选项时使用 HTTP,还建议在客户端中将此设置为 false。

        /// <summary>
        /// Gets or sets if HTTPS is required for the metadata address or authority.
        /// The default is true. This should be disabled only in development environments.
        /// </summary>
        public bool RequireHttpsMetadata { get; set; } = true;
    

    如果您设法访问 IdentityServer 登录页面,那么在 URL 中您将找到实际发送到 IdentityServer 的 redirectURL。或者使用 fiddler 捕获请求以查看传递给身份服务器的 requestUrl 是什么。

    当我查看屏幕截图时,您在 allowedRedirectURis 中有端口 5009,在请求中有 5008。

    【讨论】:

    • 谢谢托雷。做了你的建议,但仍然没有运气。我的 IdentityServer 抛出一个错误,上面写着“无效的 redirect_url:localhost:6008/signin-oidc”。但是在我的 IdentityServer 客户端配置中,我有“RedirectUris = {“localhost:6008/signin-oidc”}”。在 MVC 中我有:“applicationUrl”:“localhost:6008”。 (我什至尝试从重定向 url 中删除“/signin-oidc”,以便双方完全匹配)。我还设置了“options.RequireHttpsMetadata = false;”在我的 MVC 启动的 ConfigureServices 中。结果是一样的——同样的错误。有什么想法吗?
    • 请发一份你的创业课程副本
    • 在上面的评论中,每个网址前面都应该有一个“http://”。不知道为什么帖子隐藏了它们。
    • Tore,我已经发布了我的启动类(MVC 和 IdentityServer)作为答案,因为它们在评论中没有修复。再次感谢。
    • 撕了,我从来没有进入过登录页面。但是控制台窗口会显示这些 url 和错误消息。我已经更新了我上一个“anwser”帖子以包含这些屏幕截图。再次感谢!
    【解决方案2】:

    这是我的 MVC 启动

        public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
    
        public IConfiguration Configuration { get; }
    
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
    
            services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";
            })
            .AddCookie("Cookies")
            .AddOpenIdConnect("oidc", options =>
            {
                // The default is true. This should be disabled only in development environments!!!
                options.RequireHttpsMetadata = false;
    
                options.Authority = "https://localhost:5005";
    
                options.ClientId = "mvc";
                options.ClientSecret = "secret";
                options.ResponseType = "code";
    
                options.SaveTokens = true;
    
                options.Scope.Add("profile"); 
                options.Scope.Add("email"); 
                options.GetClaimsFromUserInfoEndpoint = true; 
    
                options.Scope.Add("MyAPI"); 
                options.Scope.Add("offline_access"); 
            });
        }
    
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();
    
            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();
    
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}")
                    .RequireAuthorization(); 
            });
        }
    }
    

    这是 IdentityServer 的启动

    public class Startup
    {
        public IWebHostEnvironment Environment { get; }
        public IConfiguration Configuration { get; }
    
        public Startup(IWebHostEnvironment environment, IConfiguration configuration)
        {
            Environment = environment;
            Configuration = configuration;
        }
    
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
    
            var migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
    
            var connstr = Configuration.GetConnectionString("MyIDSConnection");
            services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connstr));
    
            services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();
    
            var builder = services.AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseSuccessEvents = true;
    
                options.EmitStaticAudienceClaim = true;
            })
                .AddAspNetIdentity<ApplicationUser>()
                .AddConfigurationStore(options =>
                {
                    options.ConfigureDbContext = b => b.UseSqlServer(connstr,
                        sql => sql.MigrationsAssembly(migrationsAssembly));
                })
                .AddOperationalStore(options =>
                {
                    options.ConfigureDbContext = b => b.UseSqlServer(connstr,
                        sql => sql.MigrationsAssembly(migrationsAssembly));
                });
    
            // not recommended for production - you need to store your key material somewhere secure
            builder.AddDeveloperSigningCredential();
            //services.AddIdentityServer().AddSigningCredential(
            //    new X509Certificate2(Path.Combine(_environment.ContentRootPath, "certs", "IdentityServer4Auth.pfx")));
    
            services.AddAuthentication()
                .AddGoogle(options =>
                {
                    options.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
    
                    // register your IdentityServer with Google at https://console.developers.google.com
                    // enable the Google+ API
                    // set the redirect URI to https://localhost:5001/signin-google
                    options.ClientId = "";
                    options.ClientSecret = "";
                });
        }
    
        public void Configure(IApplicationBuilder app)
        {
            if (Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
    
            // uncomment if use MVC
            app.UseStaticFiles();
            app.UseRouting();
    
            // Add IdentityServer to the pipeline
            // UseIdentityServer includes a call to UseAuthentication, so it’s not necessary to have both
            app.UseIdentityServer();
            // uncomment if use MVC
            app.UseAuthorization();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
            });
        }
    
        private void InitializeDatabase(IApplicationBuilder app)
        {
            using (var serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())
            {
                serviceScope.ServiceProvider.GetRequiredService<PersistedGrantDbContext>().Database.Migrate();
                var context = serviceScope.ServiceProvider.GetRequiredService<ConfigurationDbContext>();
                context.Database.Migrate();
                serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>().Database.Migrate();
    
                if (!context.Clients.Any())
                {
                    foreach (var client in Config.Clients)
                    {
                        context.Clients.Add(client.ToEntity());
                    }
                    context.SaveChanges();
                }
    
                if (!context.IdentityResources.Any())
                {
                    foreach (var resource in Config.IdentityResources)
                    {
                        context.IdentityResources.Add(resource.ToEntity());
                    }
                    context.SaveChanges();
                }
    
                if (!context.ApiScopes.Any())
                {
                    foreach (var resource in Config.ApiScopes)
                    {
                        context.ApiScopes.Add(resource.ToEntity());
                    }
                    context.SaveChanges();
                }
            }
        }
    }
    

    这是启动时的 IdentityServer 控制台窗口

    这是启动时的 MVC 控制台窗口

    【讨论】:

      猜你喜欢
      • 2018-12-05
      • 2020-10-10
      • 1970-01-01
      • 2011-10-11
      • 2017-02-16
      • 1970-01-01
      • 2018-08-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多