With this filter enabled, no sub menus were rendered. If I take out the filter, everything works fine.
The same code worked without any problems in Q2 2011- all sub menus were rendered correctly.
26 Answers, 1 is accepted
This is caused by the new security trimming feature of the navigational components (Menu, PanelBar, TreeView, TabStrip). Before the Q3 2011 release, the global filters were not taken into account. That was very desirable functionality and we decided to introduce it in the Q3 2011 release. In order to overcome this behavior you will need to override AuthorizeCore method and return true.
Georgi Krustev
the Telerik team
Overriding AuthorizeCore method did not solve the issue. It cased only my application to bypass user's authorization. This is something I cannot do.
The sub menus were still not rendered.
Could you please send us a simple test project, which replicates the problem? Thus I will be able to observe the depicted issue and advice you further.
Georgi Krustev
the Telerik team
Please comment the line "filters.Add(new LogonAuthorize());" in RegisterGlobalFilters method in order to see the menu fully rendered. You can log on with any user name and password.
Internally we IL generate the custom authorization attribute and that is why LogonAuthorize not should not be sealed. The following snippet shows how it should look:
public
class
LogonAuthorize : AuthorizeAttribute
{
public
override
void
OnAuthorization(AuthorizationContext filterContext)
{
bool
skipAuthorization = filterContext.ActionDescriptor.IsDefined(
typeof
(AllowAnonymousAttribute),
true
)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(
typeof
(AllowAnonymousAttribute),
true
);
if
(!skipAuthorization)
{
base
.OnAuthorization(filterContext);
}
}
protected
override
bool
AuthorizeCore(HttpContextBase httpContext)
{
return
true
;
}
}
Regards, Georgi Krustev
the Telerik team
Not having OnAuthorization sealed did result in menus and sub menus properly rendering after I was logged in. However, before I was logged in - menus or sub menus did not render at all.
Unfortunately, I cannot override AuthorizeCode because it makes my security unusable. In the test project I sent you, Home/Index page requires authorization. With AuthorizeCore overridden everyone can see the page, which is not correct.
You still can use AuthorizeCore method and have proper security. You just need to return false if the user is not authorized:
protected
override
bool
AuthorizeCore(HttpContextBase httpContext)
{
if
(!httpContext.User.Identity.IsAuthenticated)
{
return
false
;
}
return
true
;
}
Georgi Krustev
the Telerik team
what happend to the IAuthorizeAttribute from the Telerik framework? is it still needed to do this work?
I'm really not sure about the solution that you have proposed. I'm in the same situation as Prpa and i think there's no way to test if the Action method have AllowAnonymousAttribute and let the user pass or not.
If you had to do the same thing as us with the AllowAnonymous, how would you test it to work with Telerik?
The security trimming functionality depends on the AuthorizeCore method. The approach with the "AllowAnonymous" attribute cannot be achieved using AuthorizeCode though. In other words show/hide menu items depending on the "AllowAnonymous" attribute is not supported.
We will further investigate this limitation and will try to provide better solution for the next official release.
Georgi Krustev
the Telerik team
Is it possible to turn the Security Trimming feature off ?
Unfortunately, it is not possible. If the issue still persists, I will need test project, which demonstrates the problem. Thus I will be able to observe it locally and advice you further.
Georgi Krustev
the Telerik team
I thought you were working on the issue! You just need to use the sample provided by Dr Prpa and you will see the problem. We need that the Menu works with our implementation of AuthorizeAttribute
. Presently, this is not the case because it doesnt response well with the logic of AllowAnonymousAttribute.alex
We are working on this issue and will try to overcome this limitation for the next official release of Telerik Extensions for ASP.NET MVC.
Georgi Krustev
the Telerik team
This is a follow-up message to inform you what is the current status of this issue.
We was able to improve the current behavior of the authorization functionality. With the made modification you can use OnAuthorization method of the AuthorizationAttribute. Check the latest internal build of the Telerik Extension for ASP.NET MVC. If you encounter any issues please let me know in order to fix them before the service pack scheduled for the begining for the January 2012.
Georgi Krustev
the Telerik team
i will give you news as soon as possible.
alex
I have confirmed that the Service Pack did fix the issue. Thank you very much.
I am glad to here that everything is OK. If you have any issues with the Menu I will suggest you download the latest internal build. Check this thread for more information.
Georgi Krustev
the Telerik team
Yes, in the next official release (this functionality is included in the latest internal build) you will be able to use OnAuthorization directly without overiding AuthorizeCore. In order words Telerik Components for ASP.NET MVC will trigger "normal" behavior of AuthorizationAttribute.
Georgi Krustev
the Telerik team
Thank you for the response.
I have tested the fix, and the OnAuthorize is indeed called. However there are a couple of problems:
First, the call seem to be in the context of a normal request for the action defined in the .Action() in the menu. IMO this should appear to be a child request. The rationale is that it is called as part of rendering another view. How we have this set up is:
When we first hit an Action, we get to the OnAuthorize() for that action. There we set up state for granting permissions needed for rendering that view. Any html.Action() or html.RenderAction() in that view will be child requests, and will not recompute the permission state. Currently the calls made by menu are not child actions, and will therefore trigger the a full computation of permissions. This will hurt performance. I am also unsure how it will affect the permission state in the "parent" action (the action/view that renders the menu). So IMO the authorization checks should be child actions (perhaps configurable).
The second issue is that we use dependency injection in the custom authorize attribute. However when the OnAuthorize is triggered by authorize checks for the menu, nothing gets injected. We are using Ninject hooked up the "standard" way in MVC 3.
It would be great if you could look into this and indicate what you think about:
- Having authorize checks appear as child actions
- Ensuring the attribute is activated from the container to ensure proper DI
BR,
Thor A. Johansen
Oppad AS
Is there something in httpContext I can inspect to see what the Telerik menu security trimming is trying to authorize?
FOR OTHERS - I have a solution for implementing your own security trimming at the bottom.
Let me follow up with the details. MVC3 .NET 4.0 with Telerik 2011.3.1306. All users are authenticated with forms authentication. I have created a custom authorization attribute that overrides AuthorizeCore. I have decorated 'some' of my controllers with the custom authorization attribute. The intent is that any authenticated user has access to any undecorated controllers,(like Home/Index) while decorated controllers are secured with authorization. My controller access works correctly but the Telerik menu security trimming does not.
The issue is that the logic in my override of AuthorizeCore is inspecting this: string controller = request.RequestContext.RouteData.Values["controller"].ToString();. The problem for me is that when the menu is security trimming, this value is always the same, it's the controller of where we are going. An httpcontext is the only parameter to the AuthorizeCore, and I can not find anything in it to differentiate between the real request authorization and the menu items. So the result is whenever I'm navigating to an undecorated controller, the menu triggers an authorization call for each item, but apparently under the context of the undecorated controller. This returns false and the menu items do not show up when they should. I need to be able to find the controller and action the menu wants to authorize in the httpcontext.
My temporary hack solution is to bypass your security trimming by using a combination the URL and Visible methods instead of the Action method. I also factored my authorization logic outside of the filter and pass it to the Visible method. So I change .Action("Index","MyController") to .URL("MyController/Index") and add .Visible(MySecurity.Authorize(User.Identity.Name, "MyController")). EDIT: I only do this for the menu items I know require authorization, not the others. I also know its a crappy hack - im just waiting for a better solution.
The HttpContext has info only for the current request. You will need to use OnAuthorization to get required information.
Georgi Krustev
the Telerik team
Replace the file at Telerik_Extensions_for_ASPNET_MVC_2012_2_607_OpenSource\Source\Telerik.Web.Mvc\Infrastructure\Implementation and compile.
#elif MVC3
var authorizeAttributes = FilterProviders.Providers.GetFilters(authorizationContext.Controller.ControllerContext, authorizationContext.ActionDescriptor).Select(f => f.Instance).OfType<IAuthorizationFilter>().ToList();
authorizeAttributes.AddRange(GlobalFilters.Filters.Select(f => f.Instance).OfType<IAuthorizationFilter>());
#endif
Thank you for sharing the code. It really solves the problem with the Arias support. We will further consider whether to include the improvement in the Telerik Extensions for ASP.NET MVC. Please note that it is a depricated product.
As a side note, the Kendo UI Complete for ASP.NET MVC already provides a support for Areas. You can check them too.
As a token of gratitude for your involvement your Telerik points have been updated.
Georgi Krustev
the Telerik team