0

I am working on a project that is using Sitecore in headless mode with DotNetCore as the rendering host. It is hosted in Docker containers but I don't think that should matter.

We have a requirement to make some items require login, when I do this the layout service returns 401. In the rendering host, you can't see to configure or handle this response, it just breaks.

Does anyone know how this should be implemented?

An unhandled exception occurred while processing the request.
ArgumentNullException: Value cannot be null. (Parameter 's')
System.IO.StringReader..ctor(string s)

Stack Query Cookies Headers Routing
ArgumentNullException: Value cannot be null. (Parameter 's')
System.IO.StringReader..ctor(string s)
Newtonsoft.Json.Linq.JObject.Parse(string json, JsonLoadSettings settings)
Newtonsoft.Json.Linq.JObject.Parse(string json)
Sitecore.AspNet.RenderingEngine.Binding.Sources.SitecoreLayoutContextPropertyBindingSource.GetModel(IServiceProvider serviceProvider, ModelBindingContext bindingContext, ISitecoreRenderingContext renderingContext)
Sitecore.AspNet.RenderingEngine.Binding.SitecoreLayoutModelBinder<T>.BindModelAsync(ModelBindingContext bindingContext)
Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BinderTypeModelBinder.BindModelAsync(ModelBindingContext bindingContext)
Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinder.BindProperty(ModelBindingContext bindingContext, ModelMetadata property, string fieldName, string modelName)
Microsoft.AspNetCore.Mvc.ModelBinding.Binders.ComplexTypeModelBinder.BindModelCoreAsync(ModelBindingContext bindingContext, int propertyData)
Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, object value)
Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider+<>c__DisplayClass0_0+<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Filters.MiddlewareFilterBuilder+<>c+<<BuildPipeline>b__8_0>d.MoveNext()
Sitecore.AspNet.RenderingEngine.Middleware.RenderingEngineMiddleware.Invoke(HttpContext httpContext, IViewComponentHelper viewComponentHelper, IHtmlHelper htmlHelper)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
Sitecore.AspNet.ExperienceEditor.ExperienceEditorMiddleware.Invoke(HttpContext httpContext)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

2 Answers 2

0

Since the pages require a login the 401 is the correct result if you try get data from the layout service when you are not logged in. There previously was a bug related to the 401. You can find more info here: https://github.com/Sitecore/jss/issues/145

I also have a JSS setup where some pages require a login. In Javascript (React) the 401 will be passed to the catch event. If we get into that event we can send the user to the login page. Here is the code:

const getRouteData = (route, language) => {
  const fetchOptions = {
    querystringParams: { sc_lang: language, sc_apikey: config.sitecoreApiKey },
    fetcher: dataFetcher,
  };

  return dataApi.fetchRouteData(route, fetchOptions).catch(error => {
    if (isBrowser()) {
      if (error.response
          && (error.response.status === 401
          || error.response.status === 403)) {
        // If we get a 401 or 403 the xhr request can't handle that.
        // So trigger a normal request which redirects to the login page.
        window.location.href = route;
      }
    }

    console.error('Route data fetch error', error, error.response);

    return null;
  });
};

Maybe you can do something similar in DotNetCore?

0

Other option can be role based access. Recently during one of the Sitecore Slack thread it's suggested to add roles On items and if user not belongs to specific role then don't show item to user.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.