如何解决 IdentityServer4 中的循环 - 连接/授权/回调?client_id=?

Posted

技术标签:

【中文标题】如何解决 IdentityServer4 中的循环 - 连接/授权/回调?client_id=?【英文标题】:how to solve the loop in IdentityServer4 - connect/authorize/callback?client_id=? 【发布时间】:2021-03-01 05:56:54 【问题描述】:

你好社区我有一个使用asp.net core、blazor webassembly和Identity4创建的项目,本地项目运行良好,我将它发布在IIS服务器上,以便可以从互联网上看到,项目加载完美,唯一的细节是,当我输入正在加载的登录名时,直到我将其清空缓存并以强制方式加载,我可以输入登录表单,然后输入我的凭据并再次保持加载,直到我清空再次缓存,进入我已经登录的页面。

如何在不清空缓存和加载的情况下输入登录表单 强行?

当我点击登录按钮时,它会将我发送到这条路线但它是错误的:

connect/authorize?client_id=BlazorApp.Client&redirect_uri=https%3A%2F%2

这是适合我的路线:

Identity/Account/Login?ReturnUrl=%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id

这是我的班级启动:

 public class Startup
    
        public Startup(IConfiguration configuration)
        
            Configuration = configuration;
            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
        

        public IConfiguration Configuration  get; 

        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
                 

            services.AddDbContext<SimulexContext>
                          (options => options.UseSqlServer(Configuration.GetConnectionString("SimulexConnection")));

           
            services.AddDefaultIdentity<ApplicationUser>(options => 
            options.SignIn.RequireConfirmedAccount = true;
            options.Password.RequireDigit = false;
            options.Password.RequireLowercase = false;
            options.Password.RequireUppercase = false;
            options.Password.RequireNonAlphanumeric = false;
            )
            .AddRoles<IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddIdentityServer()
                .AddApiAuthorization<ApplicationUser, ApplicationDbContext>()
                .AddProfileService<IdentityProfileService>();

            services.AddAuthentication()
               .AddIdentityServerJwt();

            services.Configure<PayPalConfiguration>(Configuration.GetSection("PayPal"));
           

            services.AddControllersWithViews();
            services.AddRazorPages();

           
            services.AddAutoMapper(typeof(Startup));

            
            services.AddScoped<NotificacionesService>();

            
            services.AddScoped<IAlmacenadorDeArchivos, AlmacenadorArchivosLocal>();
            
            services.AddHttpContextAccessor();

            
            services.AddMvc().AddNewtonsoftJson(options =>
            options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
        

        // 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();
                app.UseWebAssemblyDebugging();
            
            else
            
                app.UseExceptionHandler("/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.UseBlazorFrameworkFiles();
            app.UseStaticFiles();

            app.UseRouting();            
            
            app.UseAuthentication();
            app.UseIdentityServer();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            
                endpoints.MapGet("/api/config/notificacionesllavepublica", async context =>
                 
                     var configuration = context.RequestServices.GetRequiredService<IConfiguration>();
                     var llavePublica = configuration.GetValue<string>("notificaciones:llave_publica");
                     await context.Response.WriteAsync(llavePublica);
                 );

                endpoints.MapRazorPages();
                endpoints.MapControllers();              
                endpoints.MapFallbackToFile("index.html");
            );
        
    

这是我的页面 appsettingsjson:

"IdentityServer": 
    "Key": 
      "Type": "Development"
    ,
    "Clients": 
      "BlazorApp.Client": 
        "Profile": "IdentityServerSPA"
      
    
  ,

【问题讨论】:

【参考方案1】:

您能分享一下您的 blazor 应用启动吗?

几周前我遇到了同样的问题,但是在与配置了身份的 is4 集成时使用了一个 asp.net mvc 应用程序。所以对你来说可能是一样的。

Enet 的解决方案可能有效,但我还没有尝试过。下面是另一种解决方案,仅当您在 Blazor 应用程序中配置了身份时才对我有用。尝试在 services.AddAuthenticationAddOpenIdConnect 中设置方案:

services.AddAuthentication(options =>

    options.DefaultScheme = "Cookies";
    options.DefaultChallengeScheme = "Oidc";
    options.DefaultAuthenticateScheme = "Cookies"; // <-- add this line
)
    .AddCookie("Cookies", options =>
    
    )
    .AddOpenIdConnect("oidc", options =>
    
        options.SignInScheme = "Cookies"; // <-- add this line
    )
;

【讨论】:

我尝试了您给我的代码作为示例,但出现以下错误:ArgumentException: Options.ClientId must be provided (Parameter 'ClientId') 此代码适用于 blazor 应用程序,我删除了一些我认为您已经拥有的代码,您能否更新您的问题以包含 blazor 应用程序 startup.cs 代码? 你需要哪个启动类?已经在上面发布了我的启动类 上述从 blazor 或 identityserver4 启动? 我把identity4放到了blazor webassembly项目中,identity4配置在启动类中

以上是关于如何解决 IdentityServer4 中的循环 - 连接/授权/回调?client_id=?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 IdentityServer4 访问令牌和 [Authorize] 属性

如果用户从 IdentityServer4 中的另一个浏览器/设备登录,如何检测并从应用程序中注销用户?

带有存储在 cookie 中的刷新令牌的 SPA - 如何使用 IdentityServer4 进行配置?

如何通过自省验证 IdentityServer4 访问令牌

如何使用来自另一个项目 api 的 IdentityServer4 UserManager 方法

如何从 identityServer4 的现有数据库中获取用户