Some time back, (I cannot remember when) I was warned that ReuseScope.Request
may not be reliable.
I am not sure what the status of ReuseScope.Request
is now, but we are proceeding with ReuseScope.Request` and we are getting some strange intermittent behaviour that is very hard to pin down, and wondering if it might be related to this scope or not.
(I am simply trying to determine whether to look into this as a potential problem or look elsewhere, since we are having quite the problem identifying precisely what is causing our problem.
I have a dependency defined like this, which is injected into all our services:
public class AuthSessionCurrentCaller : ICurrentCaller, IRequiresRequest
{
private IRequest currentRequest;
private IAuthSession currentSession;
public string Username
{
get
{
var sess = GetSession();
if (sess == null)
{
return null;
}
return sess.UserName;
}
}
public string Id
{
get
{
var sess = GetSession();
if (sess == null)
{
return null;
}
return sess.UserAuthId;
}
}
public string AccessToken
{
get
{
var sess = GetSession();
if (sess == null)
{
return null;
}
var tokens = sess.ProviderOAuthAccess.SafeList();
if (!tokens.Any(tk => tk.Provider.EqualsIgnoreCase(OAuth2AccessTokenAuthProviderReader.Name)))
{
return null;
}
return tokens.First(tk => tk.Provider.EqualsIgnoreCase(OAuth2AccessTokenAuthProviderReader.Name)).AccessToken;
}
}
public IEnumerable<string> Roles
{
get
{
var sess = GetSession();
if (sess == null)
{
return Enumerable.Empty<string>();
}
return sess.Roles.Safe();
}
}
public bool IsAuthenticated
{
get
{
var sess = GetSession();
if (sess == null)
{
return false;
}
return sess.IsAuthenticated;
}
}
public bool IsInRole(string role)
{
return Roles.Any(r => r.EqualsIgnoreCase(role));
}
public IRequest Request
{
get { return this.currentRequest; }
set
{
this.currentRequest = value;
this.currentSession = null;
}
}
private IAuthSession GetSession()
{
if (this.currentRequest == null)
{
return null;
}
if (this.currentSession == null)
{
this.currentSession = this.currentRequest.GetSession();
}
return this.currentSession;
}
}
Where ICurrentCaller
is our own interface to identify the calling user of the service (i.e Id, Username, Roles, etc) , and IRequiresRequest
is our own marker interface, that is used like this, so that we can inject the IRequest
into it every request.
public override object OnPreExecuteServiceFilter(IService service, object request, IRequest httpReq, IResponse httpRes)
{
service.InjectRequestIntoServiceDependencies(httpReq);
return base.OnPreExecuteServiceFilter(service, request, httpReq, httpRes);
}
Where InjectRequestIntoServiceDependencies()
enumerates all the public properties of a service (and all the sub-dependencies of those properties recursively) looking for any property that derives from IRequiresRequest
, and when found, injects the instance of the IRequest
into that property.
OK, so our singleton instance of AuthSessionCurrentCaller
is registered (in AppHost) like this:
appHost.Container.Register<ICurrentCaller>(x => new AuthSessionCurrentCaller())
.ReusedWithin(ReuseScope.Request);
So all the services in our AppHost should be using a singleton instance of AuthSessionCurrentCaller
, which should then at any given time, have an instance of the current IRequest
that the web service is handling. (that’s the intention at least).
OK, so all fine and dandy, we think.
The ICurrentCaller
instance is injected into all our services and used throughout the life cycle of every service operation.
But unfortunately we are seeing intermittently that the identity of the user appears to change (specifically AuthSessionCurrentCaller.Roles) sometimes changes during a single request for some reason, that we cannot figure out. (Very hard to repro)
I am just wondering if anyone can see an obvious issue with this setup, where we might not be getting different requests/sessions mixed up with each other?
For example, could the session values change during the service operation lifecycle (we certainly are not doing this after the request is Pre-Authenticated), or could things like having a SSE server (also registered in the same AppHost) be mucking with the the current Request or Session values?