我对 Servicestack 身份验证有一个奇怪的问题。我开发了一个 Asp .Net Core web 应用程序(.net core 3.1),其中实现了带有凭据身份验证提供程序的 servicestack 身份验证。如果我使用任何浏览器进行身份验证,一切都会正常工作。
相反,如果我尝试使用指向 servicestack /auth/{provider} api 的 JsonServiceClient 从外部应用程序进行身份验证,我会遇到这个问题:身份验证进行顺利,但JsonServiceClient 对象将 SessionId 存储在 cookie(s-id/s-pid)中,不同于AuthenticateResponse 的 SessionId。这是我的例子。
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();
如果我检查 cookies 变量中的值,我会发现s-id和s-pid与响应的 sessionId 完全不同。
另一个奇怪的事情是,如果我在这些代码行下第二次重复身份验证,现在s-pid cookie 等于响应的 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());
}
}