Submitting a form tries to get BackOfficeIdentity and throws Null exception if not logged in
Edit: I found out that the issue is appearing since upgrading from Umbraco Forms 7.03 to 7.07 on July 20 due to the security patch. We have also tested it on v7.1.4 and see the same behaviour.
Hi, I'm having an issue with a Umbraco v7.1.5.4 site that has multiple forms that throw an Internal server error when trying to submit a form.
When logged in as an Administrator, no error appears. The workflow is configured to send a confirmation e-mail, which does work in both cases. However, the data is not actually saved in "Entries" in Umbraco when the error appears (i.e. the user is not logged in as Admin).
Although we have custom workflows, I can't see them doing anything related to the user session. Besides, the errors appearing in the logs have a completely Umbraco-internal stack trace.
This is the error that we keep getting over and over:
2021-10-19 11:08:09,043 [P26768/D2/T113] ERROR Umbraco.Core.UmbracoApplicationBase - An unhandled exception occurred
System.ArgumentNullException: Value cannot be null.
Parameter name: http
at Umbraco.Core.Security.AuthenticationExtensions.GetCurrentIdentity(HttpContextBase http, Boolean authenticateRequestIfNotFound)
at Umbraco.Web.Security.WebSecurity.GetUserId()
at Umbraco.Web.Security.WebSecurity.get_CurrentUser()
at Umbraco.Forms.Web.Services.RecordService.GetUserameOfCurrentUser()
at Umbraco.Forms.Web.Services.RecordService.Approve(Record record, Form form)
at Umbraco.Forms.Web.Services.RecordService.Submit(Record record, Form form)
at Umbraco.Forms.Web.Controllers.UmbracoFormsController.SubmitForm(Form form, FormViewModel model, Dictionary`2 state, ControllerContext context)
at Umbraco.Forms.Web.Controllers.UmbracoFormsController.GoForward(Form form, FormViewModel model, Dictionary`2 state)
at Umbraco.Forms.Web.Controllers.UmbracoFormsController.HandleForm(FormViewModel model, Boolean captchaIsValid)
at lambda_method(Closure , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c.<BeginInvokeSynchronousActionMethod>b__9_0(IAsyncResult asyncResult, ActionInvocation innerInvokeState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`2.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_0.<InvokeActionMethodFilterAsynchronouslyRecursive>b__0()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.<>c__DisplayClass11_2.<InvokeActionMethodFilterAsynchronouslyRecursive>b__2()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass7_0.<BeginInvokeActionMethodWithFilters>b__1(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass3_6.<BeginInvokeAction>b__4()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass3_1.<BeginInvokeAction>b__1(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<>c.<BeginExecuteCore>b__152_1(IAsyncResult asyncResult, ExecuteCoreState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<>c.<BeginExecute>b__151_2(IAsyncResult asyncResult, Controller controller)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.<>c.<BeginProcessRequest>b__20_1(IAsyncResult asyncResult, ProcessRequestState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.<>c__DisplayClass285_0.<ExecuteStepImpl>b__0()
at System.Web.HttpApplication.StepInvoker.Invoke(Action executionStep)
at System.Web.HttpApplication.StepInvoker.<>c__DisplayClass4_0.<Invoke>b__0()
at Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule.OnExecuteRequestStep(HttpContextBase context, Action step)
at System.Web.HttpApplication.<>c__DisplayClass284_0.<OnExecuteRequestStep>b__0(Action nextStepAction)
at System.Web.HttpApplication.StepInvoker.Invoke(Action executionStep)
at System.Web.HttpApplication.StepInvoker.<>c__DisplayClass4_0.<Invoke>b__0()
at Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule.OnExecuteRequestStep(HttpContextBase context, Action step) in /_/WEB/Src/Web/Web/ApplicationInsightsHttpModule.cs:line 164
at System.Web.HttpApplication.<>c__DisplayClass284_0.<OnExecuteRequestStep>b__0(Action nextStepAction)
at System.Web.HttpApplication.StepInvoker.Invoke(Action executionStep)
at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
It is trying to call GetCurrentIdentity() when submitting, causing the ArgumentNullException to be thrown immediately.
Why is it doing that, when users clearly should not need to be logged in to submit a form?
When this calls into the Umbraco CMS code can see that it's throwing here.
Which suggests that the HTTP context used here, and injected into the class, is null.
Which is unexpected. What's also strange is that this same method is called seemingly without problem in the Submit method of the stack trace you've shared above. It only fails in the later Approve stage.
You mentioned custom workflows which you don't think related, and you may well be right. But really that's the only code I can see is running between these two points in the call stack, so do you think you could try this with this custom workflows deactivated or removed? At least that would isolate them being related to the issue.
Hi Andy, thank you for taking the time to look into it.
I agree that it is definitely using the wrong HTTP context. I can't think of any other reason it would ever try to get the Backoffice Identity of a regular user.
I agree that it is very strange with the workflows. The last stage is definitely the issue, because I can consistenly recreate the error when it is turned on, and don't get the error when it is turned off.
The really confusing part is though, that the stage runs absolutely fine and sends a confirmation e-mail no matter the error or not. The stack trace also doesn't include any of our custom code, only Umbraco and .NET internal namespaces.
And all of this only happened after upgrading Forms from 7.03 to 7.07, without any code changes to the workflow. I think we will try to upgrade Forms to a more recent version to try and see whether that helps. Alternatively, we might have to find a different way of performing the last step, even though it makes no sense why it wouldn't work.
It's actually trying to retrieve the current user (in the sense of HttpContext.User) here - which may not be a back-office identity. It could be for an approval if done via the back-office, or it could be a logged in Umbraco member if for the submission or the approval if it's automatic (as it is in your case). Or of course it could be null for an anonymous user.
Would just add too I don't think this is actually related to the security patch, as the changes weren't in this area - my guess is if you upgraded to one of the intermediate patch releases you would also see the issue, as probably whatever change that has caused this happened in one of those.
Would you mind sharing the code for the custom workflow that's triggering the issue? You can email me at abl AT umbraco DOT dk if you prefer to do so privately.
In case anyone comes across this post and has the same issue: we were using UmbracoContext.EnsureContext() in our custom workflow to get the current Umbraco context. This was done in a using block, which disposes of the context when done.
In between 7.0.3 and 7.0.7, there must have been a change in Umbraco Forms which uses this context later on in the execution internally, which then throws our exception.
The solution to it was to simply remove the using-syntax and get the context normally, without disposing of it.
Submitting a form tries to get BackOfficeIdentity and throws Null exception if not logged in
Edit: I found out that the issue is appearing since upgrading from Umbraco Forms 7.03 to 7.07 on July 20 due to the security patch. We have also tested it on v7.1.4 and see the same behaviour.
Hi, I'm having an issue with a Umbraco v7.1.5.4 site that has multiple forms that throw an Internal server error when trying to submit a form.
When logged in as an Administrator, no error appears. The workflow is configured to send a confirmation e-mail, which does work in both cases. However, the data is not actually saved in "Entries" in Umbraco when the error appears (i.e. the user is not logged in as Admin).
Although we have custom workflows, I can't see them doing anything related to the user session. Besides, the errors appearing in the logs have a completely Umbraco-internal stack trace.
This is the error that we keep getting over and over:
It is trying to call GetCurrentIdentity() when submitting, causing the ArgumentNullException to be thrown immediately.
Why is it doing that, when users clearly should not need to be logged in to submit a form?
Have tried to have a trace through of what might be going on here.
The method it's throwing on seems quite innocuous:
When this calls into the Umbraco CMS code can see that it's throwing here.
Which suggests that the HTTP context used here, and injected into the class, is null.
Which is unexpected. What's also strange is that this same method is called seemingly without problem in the
Submit
method of the stack trace you've shared above. It only fails in the laterApprove
stage.You mentioned custom workflows which you don't think related, and you may well be right. But really that's the only code I can see is running between these two points in the call stack, so do you think you could try this with this custom workflows deactivated or removed? At least that would isolate them being related to the issue.
Thanks
Andy
Hi Andy, thank you for taking the time to look into it.
I agree that it is definitely using the wrong HTTP context. I can't think of any other reason it would ever try to get the Backoffice Identity of a regular user.
I agree that it is very strange with the workflows. The last stage is definitely the issue, because I can consistenly recreate the error when it is turned on, and don't get the error when it is turned off.
The really confusing part is though, that the stage runs absolutely fine and sends a confirmation e-mail no matter the error or not. The stack trace also doesn't include any of our custom code, only Umbraco and .NET internal namespaces.
And all of this only happened after upgrading Forms from 7.03 to 7.07, without any code changes to the workflow. I think we will try to upgrade Forms to a more recent version to try and see whether that helps. Alternatively, we might have to find a different way of performing the last step, even though it makes no sense why it wouldn't work.
Best regards,
Johannes
It's actually trying to retrieve the current user (in the sense of
HttpContext.User
) here - which may not be a back-office identity. It could be for an approval if done via the back-office, or it could be a logged in Umbraco member if for the submission or the approval if it's automatic (as it is in your case). Or of course it could be null for an anonymous user.Would just add too I don't think this is actually related to the security patch, as the changes weren't in this area - my guess is if you upgraded to one of the intermediate patch releases you would also see the issue, as probably whatever change that has caused this happened in one of those.
Would you mind sharing the code for the custom workflow that's triggering the issue? You can email me at abl AT umbraco DOT dk if you prefer to do so privately.
Andy
In case anyone comes across this post and has the same issue: we were using
UmbracoContext.EnsureContext()
in our custom workflow to get the current Umbraco context. This was done in ausing
block, which disposes of the context when done.In between 7.0.3 and 7.0.7, there must have been a change in Umbraco Forms which uses this context later on in the execution internally, which then throws our exception.
The solution to it was to simply remove the
using
-syntax and get the context normally, without disposing of it.is working on a reply...