ServiceStack ServiceClient хранит неправильные куки после аутентификации - PullRequest
0 голосов
/ 17 апреля 2020

У меня странная проблема с аутентификацией в Servicetack. Я разработал веб-приложение Asp. Net Core (. net core 3.1), в котором реализована аутентификация стека служб с провайдером проверки подлинности учетных данных. Все работает правильно, если я аутентифицируюсь с любым браузером.

Вместо этого, если я пытаюсь аутентифицироваться из внешнего приложения с помощью JsonServiceClient, указывающего на api servicestack / auth / {provider}, у меня есть эта проблема: аутентификация идет хорошо, но Объект JsonServiceClient хранит SessionId в файлах cookie (s-id / s-pid), отличный от SessionId AuthenticateResponse . Вот мой пример.

Authenticate request = new Authenticate()
{
  provider = "credentials",
  UserName = username,
  Password = password,
  RememberMe = true
};
var client = new JsonServiceClient(webappUrl);
AuthenticateResponse response = await client.PostAsync(request);
var cookies = client.GetCookieValues();

Если я проверяю значения в переменной cookie, я вижу, что s-id и s-pid полностью отличаются от sessionId ответ.

Другая странная вещь заключается в том, что если я повторю аутентификацию второй раз под этими строками кода, то теперь s-pid cook ie равно sessionId ответа! Почему ??

При запуске веб-приложения у меня есть следующие строки кода:

public new void ConfigureServices(IServiceCollection services)
{

  services.AddMvc(options => options.EnableEndpointRouting = false);

  // Per accedere all'httpcontext della request
  services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
  // Per accedere alla request context della request
  services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

  // Registro il json di configurazione (innietta l'appSettings)
  services.AddSingleton(Configuration);

  // Filters
  services.AddSingleton<ModulePermissionFilter>();

  services.Configure<CookiePolicyOptions>(options =>
  {
    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
    options.CheckConsentNeeded = context => false;
    options.MinimumSameSitePolicy = SameSiteMode.None;
  });

  services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme);

  ... other lines of code
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IBackgroundJobClient backgroundJobs)
{
  app.UseStaticFiles();
  app.UseCookiePolicy();
  app.UseAuthentication();

  app.UseServiceStack(new AppHost
  {
    AppSettings = new NetCoreAppSettings(Configuration)
  });
}

public class AppHost : AppHostBase
{
  public AppHost() : base("webapp", typeof(BaseServices).Assembly) { }

  // Configure your AppHost with the necessary configuration and dependencies your App needs
  public override void Configure(Container container)
  {
    SetConfig(new HostConfig
    {
        UseCamelCase = false,
        WriteErrorsToResponse = true,
        ReturnsInnerException = true,
        AllowNonHttpOnlyCookies = false,
        DebugMode = AppSettings.Get(nameof(HostConfig.DebugMode), HostingEnvironment.IsDevelopment()),

        // Restrict cookies to domain level in order to support PflowV2
        RestrictAllCookiesToDomain = !string.IsNullOrEmpty(AppSettings.Get("RestrictAllCookiesToDomain", "")) && AppSettings.Get("RestrictAllCookiesToDomain", "").ToLower() != "localhost" ? AppSettings.Get("RestrictAllCookiesToDomain", "") : null
    });

     // Create DBFactory for cache
    var defaultConnection = appHost.AppSettings.Get<string>("ConnectionStrings:Webapp");
    var dbFactory = new OrmLiteConnectionFactory(defaultConnection, SqlServerDialect.Provider);

    // Register ormlite sql session and cache
    appHost.Register<IDbConnectionFactory>(dbFactory);
    appHost.RegisterAs<OrmLiteCacheClient, ICacheClient>();
    appHost.Resolve<ICacheClient>().InitSchema();
    appHost.Register<ISessionFactory>(new SessionFactory(appHost.Resolve<ICacheClient>()));

    //Tell ServiceStack you want to persist User Auth Info in SQL Server
    appHost.Register<IAuthRepository>(new OrmLiteAuthRepository(dbFactory));
    appHost.Resolve<IAuthRepository>().InitSchema();

    var sessionMinute = appHost.AppSettings.Get("SessionTimeoutMinute", 15);

    // Adding custom usersession and custom auth provider
    Plugins.Add(new AuthFeature(() => new CustomUserSession(), new IAuthProvider[] { new CustomCredentialsAuthProvider(), new ApiKeyAuthProvider() })
    {
        HtmlRedirect = "/Account/Login", // Redirect to login if session is expired
        IncludeAssignRoleServices = false,
        SessionExpiry = TimeSpan.FromHours(sessionMinute),
    });

    Plugins.Add(new SessionFeature());
  }
}
...