Hi,

No I think(hope) I got it. I've implemented an example based on my earlier 
created SecureLink example.
There's a DataView. The items area Locations. For each item a delete link is 
created. Users with global
action permission can see and click the delete link for every Location. A user 
with action location 
can only see and click the delete link for Locations, which are allowed for 
that user.


LocationListPage.java:
----------------------------
 protected void populateItem(final Item item) {
 final Location location = (Location) item.getModelObject();
 
 item.add(new Label("name", location.getName()));


 // Delete link for testing Swarm
 SecureLink deleteLink = new SecureLink("deleteLocation") {
 private static final long serialVersionUID = 1L;

 public void onClick() {
 return;
 }
 }; 
 deleteLink.setSecurityCheck(new LocationDataSecurityCheck("deleteLocation", 
location.getName()));
 
 item.add(deleteLink);
 // end Delete link for testing Swarm

 }
 }
 

LocationDataSecurityCheck.java
------------------------------
public class LocationDataSecurityCheck extends DataSecurityCheck
{
 private static final long serialVersionUID = 1L;
 
 private String locationName;

 /**
 * Constructs a new check.
 */
 public LocationDataSecurityCheck(String securityId, String name)
 {
 super(securityId);
 locationName = name;
 }

 /**
 * @see 
org.apache.wicket.security.checks.AbstractSecurityCheck#isActionAuthorized(org.apache.wicket.security.actions.WaspAction)
 */
 public boolean isActionAuthorized(WaspAction action)
 { 
 WaspAction combinedAction = null;
 WaspAction globalAction, locationAction;
 ActionFactory factory = getActionFactory();
 
 globalAction = factory.getAction(GlobalAction.class);
 combinedAction = action.add(globalAction);
 
 // global: so everything is allowed for the user independent of the location
 if (super.isActionAuthorized(combinedAction))
 return true; 
 
 locationAction = factory.getAction(LocationAction.class);
 combinedAction = action.add(locationAction);
 
 // location: it must be checked, if the user has rights for that location
 if (super.isActionAuthorized(combinedAction))
 if (locationName.equals("dummy"))
 return true;
 
 // no permission set
 // or location permission is set, but not sufficient for the location
 return false;

 }
 
 /**
 * Checks if the user is authenticated for this component. 
 * 
 * @see ISecurityCheck#isAuthenticated()
 * @see WaspAuthorizationStrategy#isComponentAuthenticated(Component)
 */
 public boolean isAuthenticated()
 {
 return super.isAuthenticated();
 } 

}


policy file:
------------
 // Location list page - Delete link only for allowed locations
 permission ${DataPermission} "deleteLocation", "enable, location";

or: 
---
// Location list page - Delete link for all locations
permission ${DataPermission} "deleteLocation", "enable, global";

------------------------------------------------------------------------------------------------------------------------------------

 

We have a lot of WebMarkupContainers and it is not clear now, which would be 
necessary to be secure in the future.
So I tried to use the denial strategy (and it works). Every secure container is 
allowed, it has to be declined in the policy file.
(every container can be a secure container at programming time and the 
programmer has not to care about the permissions).


SecureWebMarkupContainer.java:
-------------------------------------------
public class SecureWebMarkupContainer extends WebMarkupContainer implements 
ISecureComponent
{

 private static final long serialVersionUID = 1L;

 /**
 *
 * Constructor
 *
 * @param id
 */
 public SecureWebMarkupContainer(String id)
 {
 super(id);
 setSecurityCheck(new DenialContainerSecurityCheck(this));
 }

 /**
 * 
 * @see 
org.apache.wicket.security.components.ISecureComponent#getSecurityCheck()
 */
 public ISecurityCheck getSecurityCheck()
 {
 return SecureComponentHelper.getSecurityCheck(this);
 }

 /**
 * 
 * @see 
org.apache.wicket.security.components.ISecureComponent#isActionAuthorized(java.lang.String)
 */
 public boolean isActionAuthorized(String waspAction)
 {
 return SecureComponentHelper.isActionAuthorized(this, waspAction);
 }

 /**
 * 
 * @see 
org.apache.wicket.security.components.ISecureComponent#isActionAuthorized(WaspAction)
 */
 public boolean isActionAuthorized(WaspAction action)
 {
 return SecureComponentHelper.isActionAuthorized(this, action);
 }

 /**
 * 
 * @see org.apache.wicket.security.components.ISecureComponent#isAuthenticated()
 */
 public boolean isAuthenticated()
 {
 return SecureComponentHelper.isAuthenticated(this);
 }

 /**
 * 
 * @see 
org.apache.wicket.security.components.ISecureComponent#setSecurityCheck(org.apache.wicket.security.checks.ISecurityCheck)
 */
 public void setSecurityCheck(ISecurityCheck check)
 {
 SecureComponentHelper.setSecurityCheck(this, check);
 }

}

 

DenialContainerSecurityCheck.java:
--------------------------------------------


public class DenialContainerSecurityCheck extends ContainerSecurityCheck 
{
 private static final long serialVersionUID = 1L;
 
 /**
 * Constructor
 * 
 * @param component the container
 */
 public DenialContainerSecurityCheck(MarkupContainer component)
 {
 super(component);
 }
 
 /**
 * Turns around the security check.
 * 
 * @see 
org.apache.wicket.security.checks.ComponentSecurityCheck#isActionAuthorized(org.apache.wicket.security.actions.WaspAction)
 */
 public boolean isActionAuthorized(WaspAction action)
 {
 return !super.isActionAuthorized(action);
 }
 
}

MyApplication.java:
------------------
protected void setUpHive()
{
 
factory.setAlias("DenialComponentPermission",
 
"org.apache.wicket.security.hive.authorization.permissions.ComponentPermission");

}


policy file:
------------
permission ${DenialComponentPermission} 
"${front}.ProductAreaListPage:resultHiddenPanel", "inherit, render";


I made an additional alias for the ComponentPermission, so it is clearer in the 
policy file that the permission
is in reality a declination.
We would have to pay attention on the inherit action of the page (page allowed, 
panel not).


Is it right, that the method isActionAuthorized() within the 
SecureWebMarkupContainer is never called, 
because always the method of the SecurityCheck is used ?
------------------------------------------------------------------------------------------------------------------------------------

Now I have successfully tested authorization management in a lot of different 
situations and we have decided to use Wasp/Swarm for our 
appication (where we need a very flexible rights management for the users).

For the first release I think we will store different User roles in the 
database and those user roles will correspond to the principals 
within the policy file.
But in the future we would like to store the permissions also in the database 
and administer them online. Am I right, that I will have to 
implement our own HiveFactory, which reads the data from the database and 
creates the hive ?

Andrea


 
*Von:* users@wicket.apache.org
*Gesendet:* 22.05.08 23:08:55
*An:* users@wicket.apache.org
*Betreff:* Re: filter for data in security layer



I am not sure i follow you.

According to the log the user does not have the datapermission for the dropdown.

> I tried to set the permissions like in the explanation below, but that didn't 
> work:
>
> // Welcome page
> permission ${ComponentPermission} "${front}.Welcome", "inherit, render, 
> global";
> permission ${ComponentPermission} "${front}.Welcome", "enable, global";

What is not working?


In general adding custom actions to your pages is only useful if the
page has a securitycheck that actually checks for those actions. In
the case of a welcome page that is probably overkill but for a page
showing for example customer info it would be very useful to check if
the user has global permissions and thus can see any user or local
permissions and this only is the customer is affiliated with one of
his locations. Such a check could be implemented like this.
public boolean isActionAuthorized(WaspAction action)
{
WaspAction combined = null;
WaspAction additional;
ActionFactory factory = getActionFactory();
additional = factory.getAction(Global.class);
combined = action.add(additional);
//wrapped is another isecuritycheck like a component- or classsecuritycheck
if (wrapped.isActionAuthorized(combined))
return true; //global so everything is allowed
additional = factory.getAction(Location.class);
combined = action.add(additional);
if (wrapped.isActionAuthorized(combined))
return verifyCustomerLocationMatchesUserLocations(someCustomer, theUser);
return false;
}
The custom security check in the examples simply overrides an existing
check where this check could extend AbstractSecurityCheck but the
principal is the same. You need to check your custom actions yourself.

Not sure if that at all answers your question.

Maurice

>
> Debug logging:
> 2008-05-22 14:47:57,515 DEBUG 
> org.apache.wicket.security.hive.BasicHive.addPrincipal(BasicHive.java:111) - 
> Adding 
> org.apache.wicket.security.hive.authorization.permissions.ComponentPermission 
> "xxx.yyy.zzz.front.Welcome" "access, render, enable, location, global" to 
> everybody
> 2008-05-22 14:47:57,515 DEBUG 
> org.apache.wicket.security.hive.BasicHive.addPrincipal(BasicHive.java:111) - 
> Adding 
> org.apache.wicket.security.hive.authorization.permissions.ComponentPermission 
> "xxx.yyy.zzz.front.Welcome" "access, inherit, render, location, global" to 
> everybody
>
> 2008-05-22 14:48:13,046 DEBUG 
> org.apache.wicket.Component.render(Component.java:2284) - Begin render 
> [MarkupContainer [Component id = selectLocation, page = 
> xxx.yyy.zzz.front.Welcome, path = 
> 1:formLocation:selectLocation.DropDownChoice, isVisible = true, isVersioned = 
> false]]
> 2008-05-22 14:48:13,046 DEBUG 
> org.apache.wicket.security.hive.BasicHive.hasPermission(BasicHive.java:224) - 
> Subjects[HashKey: -1185945692, sortOrder 0 = [EMAIL PROTECTED] [mailto:[EMAIL 
> PROTECTED] does not have or implies 
> org.apache.wicket.security.hive.authorization.permissions.DataPermission 
> "LocationListModel" "global"
>
> Andrea
>
> -----------------
> On Sun, May 18, 2008 at 7:26 PM, Igor Vaynberg <[EMAIL PROTECTED] 
> [mailto:[EMAIL PROTECTED]> wrote:
>> something like this should probably be filter inside the database not
>> by some external filter which forces you to load the entire dataset.
>
> No that would be foolish, but that wasn't suggested.
>
>>
>> -igor
>>
>> On Sun, May 18, 2008 at 9:39 AM, Andrea Jahn <[EMAIL PROTECTED] 
>> [mailto:[EMAIL PROTECTED]> wrote:
>>>
>>>
>>>
>>>
>>> Hi,
>>>
>>> in our application locations are administered. A user has only rights on 
>>> some of the locations, e.g. Munich, Berlin. He should be able to select one 
>>> of the allowed locations in a selection box. Then on the different pages 
>>> all data are depending on the actually selected location. For example a 
>>> DataView shows only the items, which belong to this location.
>>>
>>> Could Swarm support data filtering ?
>
> Yes, especially in 1.3.1 this is a bit cleaner dependency wise. But
> there is no out of the box solution as there are lots of framework
> combinations possible. So get ready for some heavy duty programming :)
>
>>>
>>> I found the following related message.
>>>
>>> http://markmail.org/message/hb42u5xj7xlvumm7 
>>> [http://markmail.org/message/hb42u5xj7xlvumm7] 
>>> [http://markmail.org/message/hb42u5xj7xlvumm7] (subsection4)
>>>
>>> I like the idea, that the dataproviders get some filters (only the data 
>>> which are needed should be read from the database), but where should I 
>>> store the filters for the actual selected location in the security layer ?
>>>
>>> Perhaps does someone know examples for that issue (using Wicket, Spring and 
>>> Hibernate) ?
>
> Not aware of any examples out there, but here is what we did,
> customized to your situation for as far as i understand it :)
> Suppose we have a searchpage with some filter criteria including a
> dropdown for the location. The data in this dropdown is filtered by
> the permissions the user has for this page. If he has "global"
> permissions the dropdown contains all locations. otherwise it only
> contains locations assigned to this user. The user is not required to
> select a location, if he does that location will be used but if he
> clears the selection the search will be over all allowed locations.
> clicking a row in the search results will bring him to a another page
> from where he can navigate to other pages to see different data. These
> pages can have different permissions as the search page. for example a
> user has "global" search and report permissions but only "location"
> permissions for administrative tasks.
>
> Note that if all pages behind the searchpage have the same permissions
> you might be able to skip using custom actions.
>
> To make the concept of locations clear to wasp you have to define your
> own custom actions (see the actions section in
> http://wicketstuff.org/confluence/display/STUFFWIKI/Getting+started+with+Swarm
>  
> [http://wicketstuff.org/confluence/display/STUFFWIKI/Getting+started+with+Swarm]
> and the end about changes in 1.3.1)
> Might i suggest a "global" and a "location" action. where the global
> action could (probably should) imply the location action. Note you do
> not create an action for each location you have just 1 action called
> "location" the code will later decide which location(s) that will be.
>
> Because you now want to grant global or location permissions you will
> need to duplicate each principal making sure each has a different
> name, i suggest prefixing the principals with either global or
> location. So this will give you
>
> grant principal org.MyPrincipal "global.search.something"
> {
> permission ${ComponentPermission} "org.SearchSomethingPage",
> "inherit, render, global";
> permission ${ComponentPermission} "org.SearchSomethingPage", "enable, global";
> };
> grant principal org.MyPrincipal "location.search.something"
> {
> permission ${ComponentPermission} "org.SearchSomethingPage",
> "inherit, render, location";
> permission ${ComponentPermission} "org.SearchSomethingPage", "enable,
> location";
> };
>
> (On a side note: if you have a lot of principals or extra custom
> actions this can become quite a pain to maintain, but there are hooks
> to make this easier)
>
> For the location list model of your dropdown you can use a LDM
> implementing SwarmModel where the load will look something like this
>
> if (isAuthorized(null, getActionFactory().getAction(Global.class)))
> //return all locations
> else
> // return user locations
>
> Use the various isModel..... methods on WaspAuthorizationStrategy to
> implement SwarmModel.
> No need to add an ISecurityCheck to the component itself as swarm will
> detect the secure model and use that instead. Don't forget to add a
> DataPermission to your principals with the appropriate actions.
>
> The selection model for the dropdown could be any model it just needs
> to update a filter bean which you will pass to your dao, because the
> selection might be null the filter also needs to know about which
> locations are allowed, just use the list model for that. Then in your
> dao you need to either use the selected location or the list to return
> the search results.
>
> Maurice
>
>>>
>>> Thanks in advance
>>> Andrea
>>>
>>>
>>>
>
>
>
> EINE FÜR ALLE: die kostenlose WEB.DE-Plattform für Freunde und Deine
> Homepage mit eigenem Namen. Jetzt starten! *http://unddu.de/[EMAIL PROTECTED] 
> [http://unddu.de/[EMAIL PROTECTED]
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

        



        
EINE FÜR ALLE: die kostenlose WEB.DE-Plattform für Freunde und Deine 
Homepage mit eigenem Namen. Jetzt starten! *http://unddu.de/[EMAIL PROTECTED] 
[http://unddu.de/[EMAIL PROTECTED]

Reply via email to