You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Christopher Armstrong <ca...@fastmail.com.au> on 2010/07/06 07:58:46 UTC

Using authorization to stop RENDER action doesn't work with as expected with repeater components

I'm building a Wicket-based project that uses Wasp/Swarm for
authorization. I've connected it to Spring Security to use it as an
authentication backend, and I've also used Spring Security to perform
authentication and authorization on my middle tier Spring beans.

I have a secured web page with three panels in them (ListPanelA,
ListPanelB, ListPanelC), but I only want some of them to display for
different roles. Each panel inherits from SecurePanel and the page
inherits from SecureWebPage. The panels have repeater components in them
(DataView, which has inheritance hierarchy
Component->WebMarkupContainer->AbstractRepeater ...
->AbstractPageableView->DataViewBase->DataView).

i.e.
OverviewPage
-->ListPanelA
---->DataView
-->ListPanelB
---->DataView
-->ListPanelC
---->DataView

The problem I am having is with setting component permissions on panels.
For the basic ROLE_STAFF there is no permissions on these panels, but I
have added a RENDER permission for certain users. When the page renders,
each panel still calls onBeforeRender() on each component in its
hierarchy even though the panel has no Component.RENDER authorization.
This is a problem because onBeforeRender() in AbstractRepeater still
calls AbstractRepeater.onPopulate(), which causes the pre-rendering
value loading to take place, even though later on the component is not
even rendered. In my case, I'm relying on onPopulate() not being called
so that it doesn't try to call the (secured) middle tier methods.

The relevant parts of my Swarm configuration is as follows:

grant principal
org.forge.smartdata.server.ui.security.SpringSecurityPrincipal
"ROLE_STAFF"
{
  permission ${ComponentPermission}
  "org.forge.smartdata.server.ui.management.OverviewPage", "render";
  permission ${ComponentPermission}
  "org.forge.smartdata.server.ui.management.OverviewPage", "enable";
  ...
};

grant principal
org.forge.smartdata.server.ui.security.SpringSecurityPrincipal
"ROLE_RESEARCHER"
{ 
  ...
  permission ${ComponentPermission}
  "org.forge.smartdata.server.ui.management.ListPanelA", "enable";
  permission ${ComponentPermission}
  "org.forge.smartdata.server.ui.management.ListPanelB", "enable";
};

grant principal
org.forge.smartdata.server.ui.security.SpringSecurityPrincipal
"ROLE_REGISTRAR"
{
  ...
  permission ${ComponentPermission}
  "org.forge.smartdata.server.ui.management.ListPanelB", "enable";
};

grant principal
org.forge.smartdata.server.ui.security.SpringSecurityPrincipal
"ROLE_DEPLOYER"
{
  ...
  permission ${ComponentPermission}
  "org.forge.smartdata.server.ui.management.ListPanelC", "enable";
};

In the case above, ROLE_DEPLOYER, ROLE_RESEARCHER and ROLE_REGISTRAR all
imply permission ROLE_STAFF. If I were, for example, to login as
ROLE_RESEARCHER, it should render ListPanelA and ListPanelB but not
ListPanelC. However, I am still getting the onPopulate() actions for the
ListPanelC solution.

I dug around and found out that Component.prepareRender() doesn't check
if rendering is authorized until after the beforeRender() process has
finished. However, this still seems to cause repeater components to try
and prepare themselves for rendering by populating their internal
hierarchies. 

Is there a way to circumvent this cleanly without having to put security
checking code into my page or create a different page for each user?

Thanks
Chris

-- 
  Christopher Armstrong
  carmstrong ^^AT^ fastmail dOT com /Dot/ au


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org