Using Sitecore 8.2 Update 3
I am using the Sitecore Services Client EntityService with Token authentication. When I try to access to the service after the token has expired, I should get a 403, but instead I get:
"Message": "An error has occurred.",
"ExceptionMessage": "Input string was not in a correct format.",
"ExceptionType": "System.FormatException",
"StackTrace": " at
System.Text.StringBuilder.AppendFormatHelper(IFormatProvider provider,
String format, ParamsArray args) at
System.String.FormatHelper(IFormatProvider provider, String format, ParamsArray args)
at System.String.Format(String format, Object[] args) at
Sitecore.Services.Infrastructure.Sitecore.Diagnostics.SitecoreLogger.Debug( String messageFormat, Object[] args)
at Sitecore.Services. Infrastructure.Sitecore.Security.SigningTokenProvider.ValidateToken(String token)
at Sitecore.Services.Infrastructure.Sitecore.Security.TokenDelegatingHandler.AttemptLoginWithToken(HttpRequestMessage request)\r\n
at Sitecore.Services. Infrastructure.Sitecore.Security.TokenDelegatingHandler.<SendAsync>d__0.MoveNext()\r\n
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Web.Http.HttpServer.<SendAsync>d__0.MoveNext()"
So basically, the stringbuilder blows up when trying to write to the log. How do I intercept this to handle this error more appripriately? I want the end user to get a 403.
UPDATE
This is occurring on the ValidateToken method. The token is expired, so it throws a SecurityTokenInvalidLifetimeException which then logs like os:
this._logger.Debug(string.Format("Token invalid: {0}", (object) ex), (object) this);
This is in the class SigningTokenProvider, which I could maybe replace if I could figure out how to swap it out with my own version. Its not referenced anywhere in ShowConfig, so I dont really know where to look.
UPDATE 2
I did implement replacing Sitecore's token provider as per @zacharykneibel. Once that was replaced, I determined the problem was how they are generating the error message. It generated the error message with some fixed string and an anonymous object. They then log like this:
this._logger.Debug(string.Format("Token invalid: {0}", (object) ex), (object) this);
The problem is that exception, the message contains a string representation of an object that contains items in double quotes and also brackets ({ and }) which are not escaped. This would be fine in an api call, it would com back as json, but they are logging it to the Sitecore log, where things go awry. This feels a bit hacky, but I fixed this by replacing the characters in the error message. For the above mentioned reason, I editing the logging method, and the the error itself:
his._logger.Debug(string.Format("Token invalid: {0}", ex.Message.Replace("{","{{").Replace("}","}}").Replace(@"""",@"""""")), (object)this);
I might write a method to better convert this object to a cleaner string.
To make matters worse, once this was resolved, it seemed there was no logic to prevent a call to the api if the token authentication failed. It noted that the token was no good, but it still processed the call to the api, so I had to rewrite that method as well.
Here's Sitecore method:
rotected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
this.AttemptLoginWithToken(request);
return await base.SendAsync(request, cancellationToken);
}
I will need to do something lime this:
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (!AttemptLoginWithToken(request))
{
var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
return response;
}
return await base.SendAsync(request, cancellationToken);
}