Initially, in the app host I was using the MemoryCacheClient and everything worked fine. Then I just switched it out with the Redis and I started getting a null back from the Authenticate method. However, this doesn’t happen every time which makes it difficult to troubleshoot. Sometimes it works without any issues, so the users exist. Other times it just return null. I am using SS 4.0.42.0. Any help is appreciated!
Here is my app host:
JsConfig.EmitCamelCaseNames = false;
JsConfig.IncludeNullValues = true;
JsConfig.IncludeTypeInfo = true;
var appSettings = new AppSettings();
SetConfig(new HostConfig
{
DebugMode = appSettings.Get("DebugMode", false),
EnableFeatures = Feature.All.Remove(Feature.Metadata)
});
//REDIS
//container.Register<ICacheClient>(new MemoryCacheClient());
container.Register<IRedisClientsManager>(c => new PooledRedisClientManager(appSettings.Get("RedisAddress")));
container.Register<ICacheClient>(c => (ICacheClient)c.Resolve<IRedisClientsManager>().GetCacheClient()).ReusedWithin(Funq.ReuseScope.None);
//Plugins
this.Plugins.Add(new RazorFormat());
Plugins.Add(new SessionFeature());
Plugins.Add(new AuthFeature(() => new CustomUserSession(), new IAuthProvider[] { new CredentialsAuthProvider() }));
var connStr = ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
container.Register<IDbConnectionFactory>(new OrmLiteConnectionFactory(connStr, SqlServerOrmLiteDialectProvider.Instance) { ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current) });
//Store User Data into the referenced SqlServer database
container.Register<IUserAuthRepository>(c => new OrmLiteAuthRepository(c.Resolve<IDbConnectionFactory>())); //Use OrmLite DB Connection to persist the UserAuth and AuthProvider info
And you don’t need to register the SessionFeature as it’s automatically registered by AuthFeature
//Plugins.Add(new SessionFeature());
This can be a little shorter too
container.Register<IDbConnectionFactory>(
new OrmLiteConnectionFactory(connStr, SqlServerDialect.Provider) {
ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current)
});
You may want to call InitSchema which will create any missing RDBMS tables:
Calling Authenticate() can return null if what’s returned is not an AuthenticateResponse e.g. it could be a redirect HttpResult which because of the strong AuthenticateResponse Response Type will be safe casted to null.
That didn’t work. I need the AuthenticateResponse object because I pull the Id from it. When I tried the Post and casting the result to AuthenticateResponse I got this error:
"Unable to cast object of type 'ServiceStack.HttpResult' to type 'ServiceStack.AuthenticateResponse"
Right, this is what it’s meant to happen you get the actual response object instead of null, if it’s not returning the AuthenticateResponse find out what it is returning, that will likely tell you what the issue is.
Since it’s a HttpResult find out what’s in it? i.e. is it a redirect HttpResult? to what?
Gothca. I am getting a 302 Found. But there is my login data in the Response property.
I then also tried logging in with an invalid password and get the 302 Found but the Response property is null. So, is it a safe assumption to only check if the the Response property is null (meaning the login info was invalid) and if there is a response then it was valid?
After some more testing I am having the same issue. When I use the MemoryCacheClient it all works and I get the Response.
Cool #s=... means it was successful, #f=... means it failed. It returns #s=0 if the User was already authenticated. Was the User already Authenticated? i.e. this.GetSession().IsAuthenticated?
Is the difference then just because you’re testing after restarting the AppDomain where the Memory CacheClient is always cleared so the user is not authenticated but when you’re testing with Redis the user was already authenticated previously? If so clear the Redis Cache with FLUSHALL when you restart the AppDomain so you can compare CacheClients behavior when they both start from no state.