ServiceStack version 5.0.2
I wondered if anyone could give me a pointer to a possible cause of the error shown in the stack trace below. (I am a junior developer, so I am very new to all this.)
We have an ASP.net MVC application which has some ServiceStack.Mvc integration in it. (I suspect we are using ServiceStack's auth provider functionality to handle authentication on MVC controller action requests).
Today we witnessed errors appearing when trying to login to our Web Application. Below is the stack trace of one of the errors that appeared.
The Index action on "MyController" has an 'Authenticate' attribute on it.
[Authenticate]
public class MyController : ServiceStackController<AuthUserSession>
All I can deduct from the stack trace is that after the MVC controller action is invoked, the service stack ServiceRunner tries to execute a service (I have no idea which one) and there is somekind of null reference within the execute method which is throwing an exception.
I wondered if Myths or anyone else had ever seen this before, or could shed any light whatsoever on what service the service runner may have been trying to execute or any information on a possible cause.
The issue disappeared after the web server was rebooted
Exception type: NullReferenceException
Exception message: Object reference not set to an instance of an object.
Stack trace: at ServiceStack.DtoUtils.CreateErrorResponse(Object request, Exception ex)
at ServiceStack.Host.ServiceRunner`1.HandleException(IRequest request, TRequest requestDto, Exception ex)
at ServiceStack.Host.ServiceRunner`1.Execute(IRequest request, Object instance, TRequest requestDto)
at ServiceStack.Host.ServiceRunner`1.Process(IRequest requestContext, Object instance, Object request)
at ServiceStack.Host.ServiceExec`1.Execute(IRequest request, Object instance, Object requestDto, String requestName)
at ServiceStack.Host.ServiceRequestExec`2.Execute(IRequest requestContext, Object instance, Object request)
at ServiceStack.Host.ServiceController.ManagedServiceExec(ServiceExecFn serviceExec, IService service, IRequest request, Object requestDto)
at ServiceStack.Host.ServiceController.<>c__DisplayClass36_0.<RegisterServiceExecutor>b__0(IRequest req, Object dto)
at ServiceStack.Host.ServiceController.Execute(Object requestDto, IRequest req)
at ServiceStack.InProcessServiceGateway.ExecSync[TResponse](Object request)
at ServiceStack.InProcessServiceGateway.Send[TResponse](Object requestDto)
at MyApplication.Controllers.MyController.Index()
I've not seen this error before, but the StackTrace originated from your MyController.Index() Action.
The ServiceStackController doesn't use the Gateway, neither does the ExecuteServiceStackFilters which executes the AuthenticateAttribute on your MVC Controller. So I'd say it's something in your MyController.Index() implementation that's causing it.
Related
I have a very simple servlet, which contains the following code to build a response:
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType(CONTENT_TYPE);
final PrintWriter out = response.getWriter();
// ...
My Sonar raises a critical issue with the rule: "Exceptions should not be thrown from servlet methods". Sonar explains it's a bad idea to let such exceptions be thrown:
Failure to catch exceptions in a servlet could leave a system in a
vulnerable state, possibly resulting in denial-of-service attacks, or
the exposure of sensitive information because when a servlet throws an
exception, the servlet container typically sends debugging information
back to the user. And that information could be very valuable to an
attacker.
But if I understand their example, I cannot figure how to manage smartly the potential IOException on response.getWriter().
Some people can explain me when this statement can raise an exception, and how/why it's important to manage it by our-self?
EDIT:
I accepted the first answer despite that I was a little frustrated. I understand very well it's a bad practice to let the servlet container manages this exception as the default behavior expose the stacktrace and possible other sensitive information to the world.
In my case, the HTTP end-point was used for internal monitoring. So in my case, I wanted to expose (relevant) information and the question was HOW I can do that if I have no PrintWriter...
What I did: my program prints an error log and it returns an HTTP error code with no content. I don't know if it can really happen... but Sonar and me are happy.
By throwing an exception in a servlet you expose the stacktrace and possible other sensitive information to the world. You should catch the exception and print/show a nice error message.
It's simple: assume all the consumers your service has are idiots and need to be treated with kid gloves - that means sending them a nicely formatted error message with a description of your choosing instead of the whole Exception.
Before asking a separate question I've done lots of googling about it and added a comment in the already existing stackoverflow question.
I have a SignalR Hub (tried both v. 1.1.3 and 2.0.0-rc) in my server with the below code:
[HubName("TestHub")]
public class TestHub : Hub
{
[Authorize]
public void TestMethod(string test)
{
//some stuff here
Clients.Caller.NotifyOnTestCompleted();
}
}
The problem persists if I remove the Authorize attribute.
And in my iOS client I try to call it with the below code:
SRHubConnection *hubConnection = [SRHubConnection connectionWithURL:_baseURL];
SRHubProxy *hubProxy = [hubConnection createHubProxy:#"TestHub"];
[hubProxy on:#"NotifyOnTestCompleted" perform:self selector:#selector(stopConnection)];
hubConnection.started = ^{
[hubProxy invoke:#"TestMethod" withArgs:#[#"test"]];
};
//received, error handling
[hubConnection start];
When the app starts the user is not logged in and there is no open SignalR connection. The users logs in by calling a Login service in the server which makes use of WebSecurity.Login method. If the login service returns success I then make the above call to SignalR Hub and I get the server error 500 with description "The ConnectionId is in the incorrect format.".
The full server stacktrace is the following:
Exception information:
Exception type: InvalidOperationException
Exception message: The ConnectionId is in the incorrect format.
at Microsoft.AspNet.SignalR.PersistentConnection.GetConnectionId(HostContext context, String connectionToken)
at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext context)
at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.ProcessRequest(HostContext context)
at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(IDictionary`2 environment)
at Microsoft.Owin.Mapping.MapMiddleware.<Invoke>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar)
at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Request information:
Request URL: http://myserverip/signalr/signalr/connect?transport=webSockets&connectionToken=axJs EQMZxpmUopL36owSUkdhNs85E0fyB2XvV5R5znZfXYI/CiPbTRQ3kASc3 mq60cLkZU7coYo1P fbC0U1LR2rI6WIvCNIMOmv/mHut/Unt9mX3XFkQb053DmWgCan5zHA==&connectionData=[{"Name":"testhub"}]
Request path: /signalr/signalr/connect
User host address:
User:
Is authenticated: False
Authentication Type:
Thread account name: IIS APPPOOL\DefaultAppPool
Thread information:
Thread ID: 14
Thread account name: IIS APPPOOL\DefaultAppPool
Is impersonating: True
Stack trace: at Microsoft.AspNet.SignalR.PersistentConnection.GetConnectionId(HostContext context, String connectionToken)
at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(HostContext context)
at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.ProcessRequest(HostContext context)
at Microsoft.AspNet.SignalR.PersistentConnection.ProcessRequest(IDictionary`2 environment)
at Microsoft.Owin.Mapping.MapMiddleware.<Invoke>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.Owin.Host.SystemWeb.IntegratedPipeline.IntegratedPipelineContext.EndFinalWork(IAsyncResult ar)
at System.Web.HttpApplication.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
I understand this is some kind of authentication and user identity mismatching but up to now I have found no way of solving it. All other questions suggest stoping the opened connection when the user identity changes but as I mentioned above I have no open connection before the user logs in successfully.
Any help would be much appreciated.
Thank you.
Here is what I found, I am trying to create a Flex/AS3 client for signalR. It only uses websockets but for my work I control both ends of the system so I know my backend will support it.
Anyway, the trick to getting around this for me was encoding the connectionToken. The server side signalR code is trying to parse out the connection ID from the token. When you get the token from the server it comes as part of the negotiation handshake, when you try to send it back you must make sure to remove the "/" and "+" symbols and encode them as %2F and %2B respectively. In AS3 the escape or other equivalent url encoding methods left the slash presumably because it is a valid url character, but since the value is passed in the querystring it needs to be encoded.
Once I did this I stopped getting a server 500 error (The ConnectionId is in the incorrect format) and the socket opened and I received messages.
Hope this helps.
Jason
Looks like you are using https://github.com/DyKnow/SignalR-ObjC be sure to use the feature-2.0.0.beta1 branch until it is pulled into master.
We had a similar problem.
Turning off the crypto functions for the connection tokens fixed it.
Sorry I can't help further, as I'm working the iOS end not the .net end.
I have an ASP.NET Web API web service which throws a SerializationException in certain circumstances. The problem is that I'm unable to trap and log this exception server-side -- the only place it shows up is in the body of the HTTP response to the client.
I registered an ExceptionFilterAttribute as described in Exception Handling in ASP.NET Web API and verified that it works properly when I throw an exception within my controller. Unfortunately the SerializationException is being thrown during the response (after the controller) and appears to be completely swallowed up by ASP.NET. I also tried hooking Application_Error() in Global.asax.cs but it didn't show up there either.
How can I catch SerializationException exceptions during the Web API response?
If, instead of returning an object, you use the ApiController.CreateResponse() method and return a HttpResponseMessage you can then do response.Content.LoadIntoBufferAsync().Wait() and that will force the serialization to happen whilst you are still in the action and therefore can catch the exception.
BTW, Serialization of responses actually happens at the host layers(in HttpControllerHandler, when hosted in IIS and in HttpSelfhostServer, when hosted in SelfHost) which is way below the stack and not immediately after the response is returned from an action.
WebAPI Stack Poster: http://www.asp.net/posters/web-api/ASP.NET-Web-API-Poster-grayscale.pdf
That said, I am not able to come up with a straight forward way to achieve this. This is cumbersome, but may be override the default Xml and Json formatter's WriteToStreamAsync methods and try-catch-log any exceptions?
Alternatively, you can enable Web API Tracing which would log the exceptions happening during serialization. But yeah, if you do not know for the requests which cause the serialization errors, then you might want to enable tracing all the time which i am not sure is something you might want to do.
You can catch all Web API exceptions by registering an implementation of IExceptionHandler.
See Web API Global Error Handling
...there are a number of cases that exception filters can’t handle. For example:
Exceptions thrown from controller constructors.
Exceptions thrown from message handlers.
Exceptions thrown during routing.
Exceptions thrown during response content serialization .
One thing not mentioned in that article is that your IExceptionHandler must be registered, either by GlobalConfiguration.Configuration.Services.Add(...) or via an IoC container configured to be used by DependencyResolver.
In my web application I am using Spring Security and Spring MVC.
I have secured a couple of methods with #Secured annotation and configured Spring Security in such a way that when one of those methods is accessed without the proper role, the user is taken to the login page. However, I do not want that behaviour when the offending request comes from Ajax, so I implemented the custom #ExceptionHandler annotated method to determine the request's context.
This is my exception handler:
#ExceptionHandler(AccessDeniedException.class)
public void handleAccessDeniedException(AccessDeniedException ex, HttpServletRequest request, HttpServletResponse response) throws Exception {
if (isAjax(request)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
} else {
throw ex;
}
}
This way I can both handle the exception myself (for example, log an attempt of accessing the #Secured method) and then let Spring do its part and redirect the user to the login page by rethrowing the AccessDeniedException. Also, when the request comes from Ajax I set the response status to SC_UNAUTHORIZED and handle the error on the client side.
Now, this seems to be working fine, but I am getting the following ERROR each time I rethrow the exception from the handleAccessDeniedException method:
ERROR org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Failed to invoke #ExceptionHandler method: public void app.controller.BaseController.handleAccessDeniedException(org.springframework.security.access.AccessDeniedException,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.lang.Exception
org.springframework.security.access.AccessDeniedException:
at app.controller.BaseController.handleAccessDeniedException(BaseController.java:23)
at app.controller.BaseController$$FastClassByCGLIB$$8f052058.invoke(<generated>)
at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
(...)
I have not added any exception handling specifics to spring xml configuration files.
I do not see any issues with the app itself, but the error is there and since I am quite new to Spring MVC and Spring Security, I am guessing that I am not doing this properly. Any suggestions? Thanks!
Your exception handler isn't supposed to throw another exception. It's supposed to deal with it and send a response. It's a good idea to check the code if you get an error from a class to see how it behaves.
For the non-ajax case, you'd be better to redirect the response to the login page, if that's what you want. Alternatively, you can customize the AuthenticationEntryPoint used by Spring Security instead and omit AccessDeniedExceptions from MVC handling. The behaviour would essentially be the same as the defaul LoginUrlAuthenticationEntryPoint but you would extend it to return a 403 when an ajax request is detected.
I have an ASMX web service running under IIS7 in classic mode. This service has the following code:
try
{
env.ExternalIP = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
catch (Exception ex)
{
LogWriter.WriteError(ex);
env.ExternalIP="000.000.000.000";
}
This results in the following stack trace. I only modified the names of usercode call stack here to protect the innocent:
Message: An Exception of type: NullReferenceException occured in method: GetAdditionalServerVar
ExceptionMsg: Object reference not set to an instance of an object.
===Stack Trace===
at System.Web.Hosting.ISAPIWorkerRequestInProc.GetAdditionalServerVar(Int32 index)
at System.Web.Hosting.ISAPIWorkerRequestInProc.GetServerVariable(String name)
at System.Web.HttpRequest.AddServerVariableToCollection(String name)
at System.Web.HttpRequest.FillInServerVariablesCollection()
at System.Web.HttpServerVarsCollection.Populate()
at System.Web.HttpServerVarsCollection.Get(String name)
at System.Collections.Specialized.NameValueCollection.get_Item(String name)
at MyService.MyMethod()
I'm at a loss here as this is very basic plain vanilla code.
EDIT
This gets even stranger. I have added some basic code just wondering what server variables I can get at this point. This fails with the same exception when I try and get all the keys:
System.NullReferenceException: Object
reference not set to an instance of an
object. at
System.Web.Hosting.ISAPIWorkerRequestInProc.GetAdditionalServerVar(Int32
index) at
System.Web.Hosting.ISAPIWorkerRequestInProc.GetServerVariable(String
name) at
System.Web.HttpRequest.AddServerVariableToCollection(String
name) at
System.Web.HttpRequest.FillInServerVariablesCollection()
at
System.Web.HttpServerVarsCollection.Populate()
at
System.Web.HttpServerVarsCollection.get_AllKeys()
at MyService.MyHelper()
When I was looking at the framework code looks like this could happen when the array which caches the server variables isn't populated and it looks like this occurs when there a null pointer to some Context...which seems like a fairly core piece of the framework code.
I suppose it's time to burn up one of our support tickets with Microsoft.
Going through my old questions. I believe this was caused by a bug in either .net or IIS. Essentially, the web service was marked as Oneway. By doing so the user was disconnected before the handler was executed so unless you managed to access the Request variables prior to the handler executing you would encounter a null reference exception.
The workaround was to add an HTTP module which accessed the property earlier in the pipeline before the client was sent the response and the handler was executed.
Have you tried getting the ip directly from HttpContext.Current.Request.UserHostAddress?
It seems that it is not always populated depending on the proxies... http://haacked.com/archive/2006/10/11/A_Gotcha_Identifying_the_Users_IP_Address.aspx