We are using a modified version of the OAuth2 Provider from the Forge. It's been in production for some time now and works as expected. We are working with an RPA product to integrate with OutSystems. Annoyingly, the RPA doesn't support OAuth2 out of the box, but it can be emulated by performing the sequence of calls to the Identity provider to get a token using an HTTP POST command and then the URI and method it needs to consume.
This all works perfectly fine in Postman, but we're getting a The format of value '' is invalid. error when we try the same with the RPA product. The logging of the RPA tool doesn't show anything unusual with the request:
The format of value '' is invalid.
POST /Identity/rest/oauth/token HTTP/1.1 Host: luci.xxxxxxxx.net User-Agent: AutoMate Authorization: Basic MGJhMjU1ZmFkMWY5NDI0MTA5Y2I6ZjU1ZmYxOTg3MzMx Accept-Encoding: gzip, deflate Connection: keep-alive Content-Length: 45 grant_type=client_credentials&scope=write:oms Received headers: HTTP/1.1 500 Internal Server Error Cache-Control: no-cache Pragma: no-cache Content-Type: application/json; charset=utf-8 Expires: -1 Server: Microsoft-IIS/10.0 X-Frame-Options: SAMEORIGIN Content-Security-Policy: frame-ancestors 'self' Date: Tue, 17 Dec 2019 23:31:44 GMT Content-Length: 66
Full Logging is enabled in Service Center, but because of the error, I can only see the stack trace, not the request received to evaluate if what the RPA logs say was sent was actually sent:
Error Message:The format of value '' is invalid. Stack:The format of value '' is invalid. at System.Net.Http.Headers.HttpHeaderParser.ParseValue(String value, Object storeValue, Int32& index) at System.Net.Http.Headers.MediaTypeHeaderValue.Parse(String input) at OutSystems.RESTService.Formatters.TextMediaTypeFormatter.CanReadType(Type type) at System.Net.Http.Formatting.MediaTypeFormatterCollection.FindReader(Type type, MediaTypeHeaderValue mediaType) at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken) at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken) at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger) at System.Web.Http.ModelBinding.FormatterParameterBinding.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.HttpActionBinding.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Filters.AuthorizationFilterAttribute.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Web.Http.Controllers.ExceptionFilterResult.d__0.MoveNext()
It is also not possible to perform a debug trace in Service Center, as the error seems to occur in the platform's API handlers before the debugger can capture the request.
Any ideas on how to debug this or where there may be an issue? Some of the headers are automatically added by the RPA, but when manually added in Postman to match the request, it still works fine. I can't get Postman to generate the same error.
Hi Chris,
I'm not sure what you mean by "Full Logging is enabled in Service Center, but because of the error, I can only see the stack trace". The stack trace is visible in the Error Log, while the REST logging is visible in the Integration Log. Did you follow the steps I laid out here? If so, you should always have a logging (something that looks like the RPA logging).
Kilian - I did set the full logging, but for some reason, it didn't fully apply. After setting it again, I'm now getting the HTTP Trace:
POST https://luci.xxxxxxxx.net/Identity/rest/oauth/token HTTP/1.1 Connection: keep-alive Content-Length: 45 Accept-Encoding: gzip, deflate Authorization: Basic MGJhMjU1ZmFkMWY5NDI0MTA5Y2I6ZjU1ZmYxOTg3MzMx Host: luci.xxxxxxxx.net User-Agent: AutoMate OS-Host: luci.xxxxxxxx.net OS-Path: /Identity OS-Pta: /rest/oauth OS-Page: /token grant_type=client_credentials&scope=write:oms HTTP/1.1 500 Internal Server Error Server: Microsoft-IIS/10.0 Content-Type: application/json; charset=utf-8 {"Errors":["The format of value '' is invalid."],"StatusCode":500}
At first glance, the "Content-Type" was missing and sure enough, when added, worked as expected.
So I'm interpreting the The format of value '' is invalid. error to mean that the Content-Type header is required and a blank value is invalid. And when I look at the stack trace a little closer, it indicates an exception with the MediaTypeHeaderValue class, which deals with the MediaType property - and therefore this header value.
It might also be that by default, it expects JSON, and when it kind find it, it gives that error. What have you set for "Request Format"? It should be "Form URL Encoded", given the request.
I'm only familiar with "Request Format" property when consuming an external API. We are using OutSystems to expose an API for OAuth2...unless I'm missing something somewhere?
You are right, sorry, I didn't realize you are exposing it. For exposing, there are indeed far less options. I would've tentatively said to use the OnResponse, but unfortunately, you cannot manipulate headers in that case. I'll ask around if there's a solution.
Hi Kilian, any solution to that one?
I find it odd the Content-Type header not being sent by default.
But in any case, to add a header to a API you are exposing, you need to add a AddHeader action from the HTTPRequestHandler extension, to the API's OnRequest event. It should also work OnResponse
Gabriel
According to the documentation: "Adds an header to the current HTTP response.". I cannot seem to get it to work in the request as well. Any experience?