После входа в IdentityServer маршрут redirectUrl не открывает метод, но возвращает POST 302 - PullRequest
0 голосов
/ 17 января 2020

. Net Core 3.1

Nginx обратный прокси.

Мой пользовательский URL-адрес обратного вызова работает, но не загружается в Mvc Метод контроллера клиента. Это очень странно.

MVC Вход клиента в IdentityServer и после этого IdentityServer перенаправляет на предыдущий URL. Например, авторизовать ссылку является / Главная / Конфиденциальность. После успешного входа я буду перенаправлен на эту страницу. Это хорошо.

Но я хочу получить следующую схему:

  1. Mvc Клиент (из / Home / Privacy) выполняет вход в IdentityServer.
  2. После этого перенаправляет IdentityServer на URL Signin-CallBack, где Mvc Клиент маршрутизации вызова метода контроллера 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 перенаправляет на Предыдущая страница. Но что не так с URL обратного вызова? В Chrome: enter image description here

Я думаю, что callin-callback должен загрузить метод SignedIn. Но в логах сервера я не вижу свою отметку <<< Ok >>>, а кеш пуст. Когда я пишу неправильно url

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

Ничего не меняется. Всегда Chrome / Nginx в логах пишет POST 302 0. Я проверил этот URL на HttpGet: address.com/editor/signin-callback. И всегда заходите в логи <<< Хорошо >>>.

Это похоже на нереальный виртуальный редирект.

Я чувствую себя идиотом. Два дня на эту проблему - но безрезультатно ... Буду признателен за любую помощь.

1 Ответ

1 голос
/ 18 января 2020

Почему у вас есть этот метод?

[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}");
}
...