I have a situation where an Authentication exception is being swallowed and ignored.
NOTE: This is ServiceStack v5.7.
I have a RequestFilterAttribute against the Service Class instance, and the AuthorizeAttribute against the individual methods in the class.
This seems to be causing the RequestFilterAttribute to be executed prior to any Authentication, via an Authorize Attribute.
When running the Execute of the RequestFilterAttribute is called first.
This calls req.SessionAs<>(),
which in turn causes the ApiKeyAuthProvider.Authenticate to be called.
This throws an authorization exception, but the code still returns to code after the req.SessionAs with an empty session and continues, the exception is swallowed up and ignored.
I assume the offending code is the following:
public static IAuthSession GetSession(this IRequest httpReq, bool reload = false)
{
...
try
{
HostContext.AppHost.ApplyPreAuthenticateFilters(httpReq, httpReq.Response);
httpReq.Items.TryGetValue(Keywords.Session, out oSession);
}
catch (Exception ex)
{
Log.Error("Error in GetSession() when ApplyPreAuthenticateFilters", ex);
/*treat errors as non-existing session*/
}
}
My Service looks like this
[SolcastProductUsage] // RequestFilterAttribute
public class HistoricalService : Service
{
...
[AuthenticateSolcastProduct] // AuthenticateAttribute descendant
[SolcastProduct(SolcastProductId.TmyP50)]
public async Task<object> Get(ApiGetHistoricalRadiationTmy request)
{
InitSession<TmyData>(request);
return await GetTmy(request);
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class AuthenticateSolcastProductAttribute : AuthenticateAttribute
{
public AuthenticateSolcastProductAttribute()
{
}
public override Task ExecuteAsync(IRequest req, IResponse res, object requestDto)
{
req.Items[SolcastProductId.ItemKey] = SolcastProductMap.Instance.GetProduct(requestDto.GetType());
return base.ExecuteAsync(req, res, requestDto);
}
}
public class SolcastProductUsageAttribute: RequestFilterAttribute
{
public SolcastProductUsageAttribute() : base() { }
public override void Execute(IRequest req, IResponse res, object requestDto)
{
var product = SolcastProductMap.Instance.GetProduct(requestDto.GetType());
req.Items[SolcastProductId.ItemKey] = product;
var session = req.SessionAs<SolcastAuthUserSession>();
if (session == null)
{
throw new Exception("Unable to resolve session.");
}