This is a migrated thread and some comments may be shown as answers.
New ControllerAuthorization.IsAccessibleToUser error in Q3 2012
1 Answer 5 Views
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Jason
Top achievements
Rank 1
Jason asked on 02 Jan 2013, 10:18 PM
I ran into an issue after upgrading to the latest version of the Telerik MVC Extensions.  I'm developing a multi-tenant MVC4 application that uses a custom filter and routes to discriminate between tenants in the form {tenantId}/{controller}/{action}/{id} where tenantId is a required guid.  I am also running the application locally as a virtual application (i.e. http:\\localhost\web).

After some searching I found reports of similar issues reported in Q2 (Another ControllerAuthorization.IsAccessibleToUser error in Q2 2012) when using areas.  I dug around in the source and found some very strange logic that I assume was put into place to solve the bug with Areas:

Telerik.Web.Mvc/Infrastructure/Implementation/AuthorizationContextCache.cs (ln. 35):
#if MVC3
            if (requestContext == null)
            {
                requestContext = new RequestContext(request.HttpContext, request.RouteData);
            }
            else
            {
                requestContext.HttpContext = request.HttpContext;
                request.RouteData = request.RouteData;
            }
#else
            requestContext = new RequestContext(request.HttpContext, request.RouteData);
#endif
 
            if (routeValues != null && routeValues.TryGetValue("Area", out area))
            {
                areaName = area.ToString();
                key = areaName + " " + key;
            }
 
#if MVC3
            if (urlHelper == null)
            {
                urlHelper = new UrlHelper(requestContext);
            }
 
            requestContext.RouteData = routeDataCache.GetRouteData(key, GenerateURL(actionName, controllerName, routeValues)) ?? requestContext.RouteData;
#endif

Telerik.Web.Mvc/Infrastructure/Implementation/AuthorizationContextCache.cs 
(ln. 107):
#if MVC3
        private string GenerateURL(string actionName, string controllerName, RouteValueDictionary routeValues)
        {
            var url = urlHelper.Action(actionName, controllerName, routeValues);
 
            if (url == "/" && !string.IsNullOrEmpty(controllerName) && !string.IsNullOrEmpty(actionName))
            {
                url = string.Format("{0}{1}/{2}", url, controllerName, actionName);
            }
 
            return url;
        }
#endif

Telerik.Web.MVC\Infrastructure\Implementation\RouteDataCache.cs (ln. 48):
internal class InternalHttpRequestBase : HttpRequestBase
{
    private readonly string appRelativeUrl;
 
    public InternalHttpRequestBase(string appRelativeUrl)
    {
        this.appRelativeUrl = appRelativeUrl;
    }
 
    public override string AppRelativeCurrentExecutionFilePath
    {
        get { return appRelativeUrl; }
    }
 
    public override string PathInfo
    {
        get { return ""; }
    }
}

Now I'm sure that the intention was to generate a url using the UrlHelper, and then somehow parse the url to find the route data from the route tables.  However, .Action() as used above "Generates a fully qualified URL to an action method by using the specified action name and route values" which includes the virtual application path.  Trying to look up the route from a URL that includes the virtual application path will in nearly every scenario return the wrong route.  It gets worse when the route contains a non-string (read: integer, guid, etc.) because the cast will fail when attempting to parse out the route values.

The internal implementation of InternalHttpRequestBase is incorrect and incomplete (and a pretty back kludge).  The AppRelativeCurrentExecutionFilePath property should return a relative URL from the application root, including the leading "~/".  The very first line in the Route.GetRouteData is:
string str = string.Concat(httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2), httpContext.Request.PathInfo);
so the route data is guaranteed to be incorrect even if you don't happen to be running in a virtual application.  If you are running in a virtual application, then the AppRelativeCurrentExecutionFilePath property would still be incorrect even if with the "~" character.  With the above behavior, there is virtually no way that the NavigationItemAuthorization functionality actually works, even in a simple scenario.

1 Answer, 1 is accepted

Sort by
0
Georgi Krustev
Telerik team
answered on 08 Jan 2013, 10:41 AM
Hello Jason,

 
I will ask to send us a simple test project, which replicates the issue in order to review the issues locally.
On the other hand I will suggest you check the Kendo UI Complete for ASP.NET MVC, where we improved authorization functionality of the navigation widgets.

Regards,
Georgi Krustev
the Telerik team
Check out the successor of Telerik MVC Extensions - Kendo UI for ASP.NET MVC - and deem it for new ASP.NET MVC development.
Tags
Menu
Asked by
Jason
Top achievements
Rank 1
Answers by
Georgi Krustev
Telerik team
Share this question
or