登录到IdentityServer后,redirectUrl路由未打开方法,但返回POST 302

问题描述 投票:0回答:1

。Net Core 3.1

Nginx反向代理。

我的自定义回调URL有效,但不会在Mvc Client控制器方法中加载。非常奇怪。

MVC客户端登录到IdentityServer,然后IdentityServer重定向到先前的URL。例如,授权链接为/ Home / Privacy。成功登录后,我将重定向到此页面。很好。

但是我想得到这个模式:

  1. 使用IdentityServer登录Mvc客户端(来自/ Home / Privacy)。
  2. 此后,IdentityServer重定向到URL登录回调,其中Mvc Client将对控制器方法SignedIn的调用路由并起作用。
  3. SignedIn重定向到先前的URL(/ Home / Privacy)。

我对第二步有问题。

MVC客户端

AccountController.cs

[HttpPost("signin-callback")]
 public IActionResult SignedIn()
 {
    _cache.SetString("message", "Good day!");
    Console.WriteLine("<<< Ok >>>");

    return View();
 }

Startup.cs

services.AddAuthentication(options =>
            {
                options.DefaultScheme = "Cookies";
                options.DefaultChallengeScheme = "oidc";

            })
                .AddCookie("Cookies", options =>
                {
                    options.Cookie.HttpOnly = true;                  
                    options.ExpireTimeSpan = TimeSpan.FromMinutes(10);
                    options.SlidingExpiration = true;
                })
                .AddOpenIdConnect("oidc", options =>
                {

                    options.Authority = $"{OpenId["Url"]}/auth";
                    options.RequireHttpsMetadata = false;
                    options.ClientId = OpenId["ClientId"];
                    options.ClientSecret = OpenId["ClientSecret"];
                    options.ResponseType = "code";
                    options.UsePkce = true;
                    options.SignInScheme = "Cookies";

                    options.CallbackPath = "/signin-callback";
                    options.GetClaimsFromUserInfoEndpoint = true;
                    options.Scope.Clear();
                    options.Scope.Add("openid");
                    options.Scope.Add("offline_access");
                    options.ClaimActions.MapJsonKey("website", "website");
                    options.SaveTokens = true;
                    options.Events = new OpenIdConnectEvents
                    {

                        OnRedirectToIdentityProvider = ctx =>
                        {
                            ctx.ProtocolMessage.RedirectUri = "http://address.com/editor/signin-callback";
                            return Task.FromResult(0);
                        },



                        OnTicketReceived = (e) =>
                       {
                           e.Properties.IsPersistent = true;
                           e.Properties.ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(60);
                           return Task.CompletedTask;
                       }
                    };

                });
       services.AddControllersWithViews();
......
}

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 {
   app.UsePathBase("/editor");
   app.UseStaticFiles();

   app.UseRouting();

   app.UseAuthentication();
   app.UseAuthorization();

app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
                endpoints.MapControllers();
            });
 }

IdentityServer

Config.cs

new Client
{
      ClientId = ...,
      ClientName = ...,
      ClientSecrets = { ...},

      AllowedGrantTypes = GrantTypes.CodeAndClientCredentials,
      RequireConsent = false,
      RequirePkce = true,
      FrontChannelLogoutSessionRequired = false,
      IdentityTokenLifetime = 300,
      AccessTokenLifetime = 1200,
      AuthorizationCodeLifetime = 300,
      AllowedCorsOrigins = {
                        "http://address.com"
      },


    RedirectUris = {
             "http://address.com/editor/signin-callback"                       
   },


   PostLogoutRedirectUris = {
                        ....
                    },
 AllowOfflineAccess = true,
 AllowAccessTokensViaBrowser = true,
 AllowedScopes = new List<string>
 {
       IdentityServerConstants.StandardScopes.OpenId,
       IdentityServerConstants.StandardScopes.Profile

 }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
 ....


services.AddIdentity<ApplicationUser, IdentityRole>(config =>
            {
                config.SignIn.RequireConfirmedEmail = true;
            })
                .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.Cors.CorsPaths.Add("/Account/AntiForgery");
                options.Cors.CorsPaths.Add("/Account/Login");
                options.Cors.CorsPaths.Add(null);
....
services.AddAuthentication();
....
services.AddCors(options =>
            {
                // this defines a CORS policy called "default"
                options.AddPolicy("CorsPolicy", policy =>
                {

                    policy.WithOrigins("http://address.com")
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowCredentials();
                });
            });

            })
}

public void Configure(IApplicationBuilder app)
        {
            app.UseCors("CorsPolicy");
            app.UsePathBase("/auth");
...
}

登录后,IdentityServer重定向到上一页。但是登录回调网址有什么问题?在Chrome中:enter image description here

我认为登录回调必须加载SignedIn方法。但是在服务器日志中,我看不到标记<<>>,并且缓存为空。当我写错网址

[HttpPost("signin-callback_what-is-wrong")]

没有任何变化。日志中的Chrome / Nginx始终写入POST 302 0。我在HttpGet上检查了该URL:address.com/editor/signin-callback。并始终获取日志<<>>。

这不是真正的虚拟重定向。

我觉得自己是个白痴。关于此问题的两天-但没有结果...我将不胜感激任何帮助。

c# asp.net-core identityserver4 openid
1个回答
0
投票

为什么有这种方法?

[HttpPost("signin-callback")]
public IActionResult SignedIn()

还有这个中间件吗?

OnRedirectToIdentityProvider = ctx =>
{
    ctx.ProtocolMessage.RedirectUri = "http://address.com/editor/signin-callback";
    return Task.FromResult(0);
},

这全部由IdentityServer处理,所以我认为您应该删除它。

在我的应用程序中,我有一个带有returnurl参数的登录按钮。单击后将调用以下方法。它没有输入,因为它是安全的。因此,首先将用户自动重定向到IdentityServer,并且仅在成功登录后才能访问该方法。保留了返回URL后,用户将被重定向回到其来源页面。

[Authorize]
public IActionResult Login(string returnUrl)
{
    if (string.IsNullOrWhiteSpace(returnUrl))
        return LocalRedirect($"~/");

    return LocalRedirect($"~{returnUrl}");
}
© www.soinside.com 2019 - 2024. All rights reserved.