Re: svn commit: r770084 - in /ofbiz/trunk/framework/example: ./ config/ data/ entitydef/ security/ servicedef/ widget/example/

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
153 messages Options
12345 ... 8
Reply | Threaded
Open this post in threaded view
|

Re: svn commit: r770084 - in /ofbiz/trunk/framework/example: ./ config/ data/ entitydef/ security/ servicedef/ widget/example/

David E Jones-3

I don't think it is common that permissions checked in the UI are  
different than permissions checked when the input from the UI is  
processed. In fact, I don't think I've ever run into that problem.

The problem I have run into over and over is that in almost every  
toolkit and framework around (with just a few exceptions) you have to  
configure or code the permission checks twice, and they often get  
accidently out of sync (causing either usability problems or security  
vulnerabilities).

If we're going to talk about extensions to the form widget or other  
things for security purposes, I think we should talk about  this  
redundancy problem because it IS an issue for the framework and one  
that people talk about when comparing the OFBiz framework to certain  
competing modern frameworks...

-David


On Apr 30, 2009, at 4:42 PM, Adrian Crum wrote:

> No, I'm not saying I disagree with you. You totally missed my point.  
> I don't think anyone is suggesting removing permissions checking  
> from the UI or the services. Let's get that settled right away.
>
> Jacopo is asking for a way to control the display of screen widgets  
> based on the user's permissions. You said: "The trick is how do we  
> setup permissions so that we set them up once and they function in  
> both places?" Maybe I'm misunderstanding your question. It sounds to  
> me like you're suggesting a single method could be used in both  
> scenarios, so I responded that the requirements are different - so a  
> single method wouldn't work.
>
> We're already using permissions to control the UI - and they are the  
> same ones used in the service calls. The problem is, it's hard to  
> implement. I believe all that's being suggested here is some new  
> widget attributes or something to make it easier.
>
> -Adrian
>
> David E Jones wrote:
>> On Apr 30, 2009, at 4:09 PM, Adrian Crum wrote:
>>> David E Jones wrote:
>>>> In other words, it is nice to check permissions on the client  
>>>> side and/or show permission impact in the UI, but that just  
>>>> improves the UI... it doesn't actually enforce any of those  
>>>> permissions checks because it is really easy to change HTML and/
>>>> or spoof a request (ie users with valid credentials that can do  
>>>> other things could then get around permissions that are only  
>>>> checked in the UI).
>>>
>>> I think Jacopo's interest is an improved UI. Why render a Create  
>>> New button when the user doesn't have the permission to create  
>>> anything?
>> Yeah, that's what I said... ie with phrases like "that just  
>> improves the UI" and "in the UI for user convenience".
>>>> The trick is how do we setup permissions so that we set them up  
>>>> once and they function in both places (ie in the input processing  
>>>> for the actual security, and in the UI for user convenience)?
>>>
>>> Is that even possible? The UI might contain multiple paths to  
>>> follow, with each path requiring a different permission. Service  
>>> invocations are generally a single path with a single permission.
>>>
>>> In other words, the UI might need to know the user's create,  
>>> update, and delete permissions in order to render the screen, but  
>>> the user action will result in only one service invocation - which  
>>> requires only one of those user permissions.
>>>
>>> I thought about this a while back, and toyed with the idea of  
>>> making the screen widgets permissions-aware.
>> So, are you saying that you disagree with what I wrote about the  
>> purposes of permissions in different places, ie:
>> 1. input processing: for security
>> 2. UI artifacts: for user convenience (improved UI)
>> Maybe what I wrote wasn't clear enough, so I'll say it again:  
>> permission checking in the UI is USELESS for security, it only  
>> helps for an improved user experience.
>> I would even go so far as to assert that if anyone doesn't  
>> understand this then they don't understand how web-based  
>> applications work, and the applications they write will be full of  
>> security holes.
>> This is why in OFBiz we REQUIRE security for services (or other  
>> input processing logic) and it is OPTIONAL in the UI.
>> -David

Reply | Threaded
Open this post in threaded view
|

Re: svn commit: r770084 - in /ofbiz/trunk/framework/example: ./ config/ data/ entitydef/ security/ servicedef/ widget/example/

Scott Gray-2
In reply to this post by Jacopo Cappellato-4
FYI and I only realized this the other day but beanshell supports exactly this type of feature where you can specify things @and, @or and etc. for use in xml files http://www.beanshell.org/manual/syntax.html#Document_Friendly_Entities

I wonder if we do this it might be worth following the same convention.

Regards
Scott


On 1/05/2009, at 5:34 AM, Jacopo Cappellato wrote:

Adrian,

this is really interesting.
However I think it is time to start thinking to define our own xml friendly keywords for && and || operators; I would like to express that statement with something like this:

<set field="hasPermission" value="${(hasPermission['update:context1'] OR hasPermission['update:context2']) AND hasPermission['update:context3']}" type="Boolean"/>

Jacopo


On Apr 30, 2009, at 7:20 PM, Adrian Crum wrote:

<set field="hasPermission" value="${(hasPermission['update:context1'] || hasPermission['update:context2']) &amp;&amp; hasPermission['update:context3']}" type="Boolean"/>

or something like that. I'm still working out the details.

-Adrian

Andrew Zeneski wrote:
That sounds cool. I'm not sure what that would really look like, but nevertheless sounds really cool! :) If you need anything from me let me know...
Andrew
On Apr 30, 2009, at 1:00 PM, Adrian Crum wrote:
Andrew Zeneski wrote:
I'd be happy to discuss additional changes as well (which aren't yet documented) like adding support to check multiple permissions at once, returning a Map of results from that permission check. So, if you or anyone else has a wish list for security, let me know so I can get it all incorporated at the same time.

Btw, I'm working on adding an extension to the UEL that will allow permission expressions.


-Adrian



smime.p7s (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: svn commit: r770084 - in /ofbiz/trunk/framework/example: ./ config/ data/ entitydef/ security/ servicedef/ widget/example/

Adrian Crum
I like that idea. Less chance that an unintended conversion would occur.

-Adrian

Scott Gray wrote:

> FYI and I only realized this the other day but beanshell supports
> exactly this type of feature where you can specify things @and, @or and
> etc. for use in xml
> files http://www.beanshell.org/manual/syntax.html#Document_Friendly_Entities
>
> I wonder if we do this it might be worth following the same convention.
>
> Regards
> Scott
>
> HotWax Media
> http://www.hotwaxmedia.com <http://www.hotwaxmedia.com/>
>
> On 1/05/2009, at 5:34 AM, Jacopo Cappellato wrote:
>
>> Adrian,
>>
>> this is really interesting.
>> However I think it is time to start thinking to define our own xml
>> friendly keywords for && and || operators; I would like to express
>> that statement with something like this:
>>
>> <set field="hasPermission" value="${(hasPermission['update:context1']
>> OR hasPermission['update:context2']) AND
>> hasPermission['update:context3']}" type="Boolean"/>
>>
>> Jacopo
>>
>>
>> On Apr 30, 2009, at 7:20 PM, Adrian Crum wrote:
>>
>>> <set field="hasPermission" value="${(hasPermission['update:context1']
>>> || hasPermission['update:context2']) &amp;&amp;
>>> hasPermission['update:context3']}" type="Boolean"/>
>>>
>>> or something like that. I'm still working out the details.
>>>
>>> -Adrian
>>>
>>> Andrew Zeneski wrote:
>>>> That sounds cool. I'm not sure what that would really look like, but
>>>> nevertheless sounds really cool! :) If you need anything from me let
>>>> me know...
>>>> Andrew
>>>> On Apr 30, 2009, at 1:00 PM, Adrian Crum wrote:
>>>>> Andrew Zeneski wrote:
>>>>>> I'd be happy to discuss additional changes as well (which aren't
>>>>>> yet documented) like adding support to check multiple permissions
>>>>>> at once, returning a Map of results from that permission check.
>>>>>> So, if you or anyone else has a wish list for security, let me
>>>>>> know so I can get it all incorporated at the same time.
>>>>>
>>>>> Btw, I'm working on adding an extension to the UEL that will allow
>>>>> permission expressions.
>>>>>
>>>>>
>>>>> -Adrian
>>
>
Reply | Threaded
Open this post in threaded view
|

Re: svn commit: r770084 - in /ofbiz/trunk/framework/example: ./ config/ data/ entitydef/ security/ servicedef/ widget/example/

Andrew Zeneski-2
I'm trying to come up with a use case where this sort of logic would  
be applicable, but I just cannot think of any. I can think of cases  
where we will conditionally want to check a single permission but OR/
AND permissions together for a UI element?

When displaying a list of items, I might add a link to an update form,  
in which I would only show the link if update permission available.  
Same with delete, but I wouldn't check these in the same place, rather  
with each link.

Also, I might use <display/> for read only users instead of text boxes  
(I really like Jacopo's use-when idea). But when would I really ever  
want to check them in an AND/OR fashion?

Keeping in mind now, that the permission system handles granularity,  
as long as we are intelligent when defining permissions I believe a  
single permissions should be able to handle most cases. With the  
exception of UIs where we would want to display different things based  
on a different base permission, even then a single call using the new  
findMatchingPermissions() would totally do the trick.

Andrew

On Apr 30, 2009, at 7:43 PM, Adrian Crum wrote:

> I like that idea. Less chance that an unintended conversion would  
> occur.
>
> -Adrian
>
> Scott Gray wrote:
>> FYI and I only realized this the other day but beanshell supports  
>> exactly this type of feature where you can specify things @and, @or  
>> and etc. for use in xml files http://www.beanshell.org/manual/syntax.html#Document_Friendly_Entities
>> I wonder if we do this it might be worth following the same  
>> convention.
>> Regards
>> Scott
>> HotWax Media
>> http://www.hotwaxmedia.com <http://www.hotwaxmedia.com/>
>> On 1/05/2009, at 5:34 AM, Jacopo Cappellato wrote:
>>> Adrian,
>>>
>>> this is really interesting.
>>> However I think it is time to start thinking to define our own xml  
>>> friendly keywords for && and || operators; I would like to express  
>>> that statement with something like this:
>>>
>>> <set field="hasPermission" value="$
>>> {(hasPermission['update:context1'] OR  
>>> hasPermission['update:context2']) AND  
>>> hasPermission['update:context3']}" type="Boolean"/>
>>>
>>> Jacopo
>>>
>>>
>>> On Apr 30, 2009, at 7:20 PM, Adrian Crum wrote:
>>>
>>>> <set field="hasPermission" value="$
>>>> {(hasPermission['update:context1'] ||  
>>>> hasPermission['update:context2']) &amp;&amp;  
>>>> hasPermission['update:context3']}" type="Boolean"/>
>>>>
>>>> or something like that. I'm still working out the details.
>>>>
>>>> -Adrian
>>>>
>>>> Andrew Zeneski wrote:
>>>>> That sounds cool. I'm not sure what that would really look like,  
>>>>> but nevertheless sounds really cool! :) If you need anything  
>>>>> from me let me know...
>>>>> Andrew
>>>>> On Apr 30, 2009, at 1:00 PM, Adrian Crum wrote:
>>>>>> Andrew Zeneski wrote:
>>>>>>> I'd be happy to discuss additional changes as well (which  
>>>>>>> aren't yet documented) like adding support to check multiple  
>>>>>>> permissions at once, returning a Map of results from that  
>>>>>>> permission check. So, if you or anyone else has a wish list  
>>>>>>> for security, let me know so I can get it all incorporated at  
>>>>>>> the same time.
>>>>>>
>>>>>> Btw, I'm working on adding an extension to the UEL that will  
>>>>>> allow permission expressions.
>>>>>>
>>>>>>
>>>>>> -Adrian
>>>

Reply | Threaded
Open this post in threaded view
|

Re: svn commit: r770084 - in /ofbiz/trunk/framework/example: ./ config/ data/ entitydef/ security/ servicedef/ widget/example/

Jacopo Cappellato-4
In reply to this post by David E Jones-3

On Apr 30, 2009, at 11:38 PM, David E Jones wrote:

>
> On Apr 30, 2009, at 11:07 AM, Jacopo Cappellato wrote:
>
>>
>> On Apr 30, 2009, at 6:50 PM, Andrew Zeneski wrote:
>>
>>> ... I'd be happy to discuss additional changes as well (which  
>>> aren't yet documented) like adding support to check multiple  
>>> permissions at once, returning a Map of results from that  
>>> permission check. So, if you or anyone else has a wish list for  
>>> security, let me know so I can get it all incorporated at the same  
>>> time.
>>>
>>> Andrew
>>
>> this is probably off topic here, but an enhancement I would like to  
>> see in the form widgets is the ability for the widget model/
>> renderer to automatically select the proper field type according to  
>> the permissions of the user: this is something that can be already  
>> done using some scriptlets and the use-when attributes but it is  
>> pretty complex.
>> I don't have a clear idea at the moment but the first options that  
>> I can think of are:
>> 1) a new field type "display-update": it will be "display" if the  
>> user has view permissions; it will be "update" if the user has  
>> write permissions
>> 2) add, a required-permission attribute to the field element: this  
>> will act as the use-when permission; or maybe adding something like  
>> use-when="${ofbiz:hasPermission(UPDATE)}"
>> 3) submit buttons will be disabled if the user doesn't have proper  
>> permissions
>> 4) base/default permissions could be set as an attribute in the  
>> form element or derived from the service (if auto-fields is used)
>
> How would we handle the "redundant" permission problem?
This is a good point.
Probably #4 in my wish list would be closer to that: we could get the  
permission service associated to the service specified by the "auto-
field" service and use it to derive the permissions for the form.
We may want to refactor the permission services to return the list of  
permissions for a given action instead of just a boolean (or in  
addition to it).
For example: the permission service, instead of answering the question:
"does the user X has UPDATE permission for the QUOTE action?"
could be refactored to answer the question:
"what are the permissions that user X has for the QUOTE process?"
if I have a form associated to the updateQuote service, but the user  
has only READ permission for the QUOTE process, then the service will  
return a permission error when called by the user, and the form will  
render as a display form, without a submit button (or with a disabled  
one).

Jacopo

>
>
> In other words, it is nice to check permissions on the client side  
> and/or show permission impact in the UI, but that just improves the  
> UI... it doesn't actually enforce any of those permissions checks  
> because it is really easy to change HTML and/or spoof a request (ie  
> users with valid credentials that can do other things could then get  
> around permissions that are only checked in the UI). Because of this  
> it is still necessary to check all permissions in services  
> processing incoming data, otherwise we have a security hole that is  
> pretty easy to exploit (well, if people realize it is there anyway).
>
> The trick is how do we setup permissions so that we set them up once  
> and they function in both places (ie in the input processing for the  
> actual security, and in the UI for user convenience)?
>
> -David
>


smime.p7s (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: svn commit: r770084 - in /ofbiz/trunk/framework/example: ./ config/ data/ entitydef/ security/ servicedef/ widget/example/

Adrian Crum-2
In reply to this post by Andrew Zeneski-2

As I mentioned in another reply, the permission expressions could replace scripts. I agree there would probably be little use for them in the UI.

-Adrian


--- On Thu, 4/30/09, Andrew Zeneski <[hidden email]> wrote:

> From: Andrew Zeneski <[hidden email]>
> Subject: Re: svn commit: r770084 - in /ofbiz/trunk/framework/example: ./ config/ data/ entitydef/ security/ servicedef/ widget/example/
> To: [hidden email]
> Date: Thursday, April 30, 2009, 7:31 PM
> I'm trying to come up with a use case where this sort of
> logic would be applicable, but I just cannot think of any. I
> can think of cases where we will conditionally want to check
> a single permission but OR/AND permissions together for a UI
> element?
>
> When displaying a list of items, I might add a link to an
> update form, in which I would only show the link if update
> permission available. Same with delete, but I wouldn't
> check these in the same place, rather with each link.
>
> Also, I might use <display/> for read only users
> instead of text boxes (I really like Jacopo's use-when
> idea). But when would I really ever want to check them in an
> AND/OR fashion?
>
> Keeping in mind now, that the permission system handles
> granularity, as long as we are intelligent when defining
> permissions I believe a single permissions should be able to
> handle most cases. With the exception of UIs where we would
> want to display different things based on a different base
> permission, even then a single call using the new
> findMatchingPermissions() would totally do the trick.
>
> Andrew
>
> On Apr 30, 2009, at 7:43 PM, Adrian Crum wrote:
>
> > I like that idea. Less chance that an unintended
> conversion would occur.
> >
> > -Adrian
> >
> > Scott Gray wrote:
> >> FYI and I only realized this the other day but
> beanshell supports exactly this type of feature where you
> can specify things @and, @or and etc. for use in xml files
> http://www.beanshell.org/manual/syntax.html#Document_Friendly_Entities
> >> I wonder if we do this it might be worth following
> the same convention.
> >> Regards
> >> Scott
> >> HotWax Media
> >> http://www.hotwaxmedia.com
> <http://www.hotwaxmedia.com/>
> >> On 1/05/2009, at 5:34 AM, Jacopo Cappellato wrote:
> >>> Adrian,
> >>>
> >>> this is really interesting.
> >>> However I think it is time to start thinking
> to define our own xml friendly keywords for && and
> || operators; I would like to express that statement with
> something like this:
> >>>
> >>> <set field="hasPermission"
> value="${(hasPermission['update:context1'] OR
> hasPermission['update:context2']) AND
> hasPermission['update:context3']}"
> type="Boolean"/>
> >>>
> >>> Jacopo
> >>>
> >>>
> >>> On Apr 30, 2009, at 7:20 PM, Adrian Crum
> wrote:
> >>>
> >>>> <set field="hasPermission"
> value="${(hasPermission['update:context1'] ||
> hasPermission['update:context2']) &amp;&amp;
> hasPermission['update:context3']}"
> type="Boolean"/>
> >>>>
> >>>> or something like that. I'm still
> working out the details.
> >>>>
> >>>> -Adrian
> >>>>
> >>>> Andrew Zeneski wrote:
> >>>>> That sounds cool. I'm not sure
> what that would really look like, but nevertheless sounds
> really cool! :) If you need anything from me let me know...
> >>>>> Andrew
> >>>>> On Apr 30, 2009, at 1:00 PM, Adrian
> Crum wrote:
> >>>>>> Andrew Zeneski wrote:
> >>>>>>> I'd be happy to discuss
> additional changes as well (which aren't yet documented)
> like adding support to check multiple permissions at once,
> returning a Map of results from that permission check. So,
> if you or anyone else has a wish list for security, let me
> know so I can get it all incorporated at the same time.
> >>>>>>
> >>>>>> Btw, I'm working on adding an
> extension to the UEL that will allow permission expressions.
> >>>>>>
> >>>>>>
> >>>>>> -Adrian
> >>>


     
Reply | Threaded
Open this post in threaded view
|

Re: svn commit: r770084 - in /ofbiz/trunk/framework/example: ./ config/ data/ entitydef/ security/ servicedef/ widget/example/

Adrian Crum
In reply to this post by jonesde
Andrew,

I thought we were getting away from using the <required-permissions>
element and using the <permission-service> element instead.

If this type of change is made in other components, it will break a lot
of code - because some components use permission service SECAs.

-Adrian

[hidden email] wrote:
> Author: jaz
> Date: Thu Apr 30 06:23:18 2009
> New Revision: 770084
>
> URL: http://svn.apache.org/viewvc?rev=770084&view=rev
> Log:
> Refactored Example Application to use new security mechanics - JIRA OFBIZ-2392

...


> Modified: ofbiz/trunk/framework/example/servicedef/services.xml
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/example/servicedef/services.xml?rev=770084&r1=770083&r2=770084&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/example/servicedef/services.xml (original)
> +++ ofbiz/trunk/framework/example/servicedef/services.xml Thu Apr 30 06:23:18 2009
> @@ -27,29 +27,37 @@
>      <!-- Example & Related Services -->
>      <service name="createExample" default-entity-name="Example" engine="entity-auto" invoke="create" auth="true">
>          <description>Create a Example</description>
> -        <permission-service service-name="exampleGenericPermission" main-action="CREATE"/>
> +        <required-permissions join-type="AND">
> +            <check-permission permission="create:example"/>
> +        </required-permissions>        
>          <auto-attributes include="pk" mode="OUT" optional="false"/>
>          <auto-attributes include="nonpk" mode="IN" optional="true"/>
>          <override name="exampleTypeId" optional="false"/>
>          <override name="statusId" optional="false"/>
> -        <override name="exampleName" optional="false"/>
> +        <override name="exampleName" optional="false"/>        
>      </service>
>      <service name="updateExample" default-entity-name="Example" engine="entity-auto" invoke="update" auth="true">
>          <description>Update a Example</description>
> -        <permission-service service-name="exampleGenericPermission" main-action="UPDATE"/>
> +        <required-permissions join-type="AND">
> +            <check-permission permission="update:example:${exampleId}"/>
> +        </required-permissions>
>          <auto-attributes include="pk" mode="IN" optional="false"/>
>          <auto-attributes include="nonpk" mode="IN" optional="true"/>
>          <attribute name="oldStatusId" type="String" mode="OUT" optional="false"/>
>      </service>
>      <service name="deleteExample" default-entity-name="Example" engine="entity-auto" invoke="delete" auth="true">
>          <description>Delete a Example</description>
> -        <permission-service service-name="exampleGenericPermission" main-action="DELETE"/>
> +        <required-permissions join-type="AND">
> +            <check-permission permission="delete:example:${exampleId}"/>
> +        </required-permissions>
>          <auto-attributes include="pk" mode="IN" optional="false"/>
>      </service>
>      <service name="createExampleStatus" default-entity-name="ExampleStatus" engine="simple"
>              location="component://example/script/org/ofbiz/example/example/ExampleServices.xml" invoke="createExampleStatus" auth="true">
>          <description>Create a ExampleStatus</description>
> -        <permission-service service-name="exampleGenericPermission" main-action="CREATE"/>
> +        <required-permissions join-type="AND">
> +            <check-permission permission="update:example:status:${exampleId}"/>
> +        </required-permissions>
>          <auto-attributes include="all" mode="IN" optional="false">
>              <exclude field-name="statusDate"/>
>              <exclude field-name="statusEndDate"/>
> @@ -58,7 +66,9 @@
>  
>      <service name="createExampleItem" default-entity-name="ExampleItem" engine="entity-auto" invoke="create" auth="true">
>          <description>Create a ExampleItem</description>
> -        <permission-service service-name="exampleGenericPermission" main-action="CREATE"/>
> +        <required-permissions join-type="AND">
> +            <check-permission permission="create:example:item:${exampleId}"/>
> +        </required-permissions>
>          <auto-attributes include="pk" mode="IN" optional="false"/>
>          <auto-attributes include="nonpk" mode="IN" optional="true"/>
>          <override name="exampleItemSeqId" mode="OUT"/> <!-- make this OUT rather than IN, we will automatically generate the next sub-sequence ID -->
> @@ -66,60 +76,78 @@
>      </service>
>      <service name="updateExampleItem" default-entity-name="ExampleItem" engine="entity-auto" invoke="update" auth="true">
>          <description>Update a ExampleItem</description>
> -        <permission-service service-name="exampleGenericPermission" main-action="UPDATE"/>
> +        <required-permissions join-type="AND">
> +            <check-permission permission="update:example:item:${exampleId}"/>
> +        </required-permissions>
>          <auto-attributes include="pk" mode="IN" optional="false"/>
>          <auto-attributes include="nonpk" mode="IN" optional="true"/>
>      </service>
>      <service name="deleteExampleItem" default-entity-name="ExampleItem" engine="entity-auto" invoke="delete" auth="true">
>          <description>Delete a ExampleItem</description>
> -        <permission-service service-name="exampleGenericPermission" main-action="DELETE"/>
> +        <required-permissions join-type="AND">
> +            <check-permission permission="delete:example:item:${exampleId}"/>
> +        </required-permissions>
>          <auto-attributes include="pk" mode="IN" optional="false"/>
>      </service>
>  
>      <!-- ExampleFeature Services -->
>      <service name="createExampleFeature" default-entity-name="ExampleFeature" engine="entity-auto" invoke="create" auth="true">
>          <description>Create a ExampleFeature</description>
> -        <permission-service service-name="exampleGenericPermission" main-action="CREATE"/>
> +        <required-permissions join-type="AND">
> +            <check-permission permission="create:example:feature"/>
> +        </required-permissions>
>          <auto-attributes include="pk" mode="OUT" optional="false"/>
>          <auto-attributes include="nonpk" mode="IN" optional="true"/>
>          <override name="description" optional="false"/>
>      </service>
>      <service name="updateExampleFeature" default-entity-name="ExampleFeature" engine="entity-auto" invoke="update" auth="true">
>          <description>Update a ExampleFeature</description>
> -        <permission-service service-name="exampleGenericPermission" main-action="UPDATE"/>
> +        <required-permissions join-type="AND">
> +            <check-permission permission="update:example:feature"/>
> +        </required-permissions>
>          <auto-attributes include="pk" mode="IN" optional="false"/>
>          <auto-attributes include="nonpk" mode="IN" optional="true"/>
>      </service>
>      <service name="deleteExampleFeature" default-entity-name="ExampleFeature" engine="entity-auto" invoke="delete" auth="true">
>          <description>Delete a ExampleFeature</description>
> -        <permission-service service-name="exampleGenericPermission" main-action="DELETE"/>
> +        <required-permissions join-type="AND">
> +            <check-permission permission="delete:example:feature"/>
> +        </required-permissions>
>          <auto-attributes include="pk" mode="IN" optional="false"/>
>      </service>
>  
>      <service name="createExampleFeatureAppl" default-entity-name="ExampleFeatureAppl" engine="entity-auto" invoke="create" auth="true">
>          <description>Create a ExampleFeatureAppl</description>
> -        <permission-service service-name="exampleGenericPermission" main-action="CREATE"/>
> +        <required-permissions join-type="AND">
> +            <check-permission permission="create:example:feature:${exampleFeatureId}"/>
> +        </required-permissions>
>          <auto-attributes include="pk" mode="IN" optional="false"/>
>          <auto-attributes include="nonpk" mode="IN" optional="true"/>
>          <override name="fromDate" optional="true"/>
>      </service>
>      <service name="updateExampleFeatureAppl" default-entity-name="ExampleFeatureAppl" engine="entity-auto" invoke="update" auth="true">
>          <description>Update a ExampleFeatureAppl</description>
> -        <permission-service service-name="exampleGenericPermission" main-action="UPDATE"/>
> +        <required-permissions join-type="AND">
> +            <check-permission permission="update:example:feature:${exampleFeatureId}"/>
> +        </required-permissions>
>          <auto-attributes include="pk" mode="IN" optional="false"/>
>          <auto-attributes include="nonpk" mode="IN" optional="true"/>
>      </service>
>      <service name="deleteExampleFeatureAppl" default-entity-name="ExampleFeatureAppl" engine="entity-auto" invoke="delete" auth="true">
>          <description>Delete a ExampleFeatureAppl</description>
> -        <permission-service service-name="exampleGenericPermission" main-action="DELETE"/>
> +        <required-permissions join-type="AND">
> +            <check-permission permission="delete:example:feature:${exampleFeatureId}"/>
> +        </required-permissions>
>          <auto-attributes include="pk" mode="IN" optional="false"/>
>      </service>
>  
>      <!-- Permission Services -->
> +    <!--  @deprecated
>      <service name="exampleGenericPermission" engine="simple"
>               location="component://example/script/org/ofbiz/example/ExamplePermissionServices.xml" invoke="exampleGenericPermission">
>          <implements service="permissionInterface"/>
>      </service>
> +    -->
>  
>      <!-- Example ServiceTest Service -->
>      <service name="testCreateExampleService" engine="simple"
Reply | Threaded
Open this post in threaded view
|

Re: svn commit: r770084 - in /ofbiz/trunk/framework/example: ./ config/ data/ entitydef/ security/ servicedef/ widget/example/

Andrew Zeneski-2
Adrian,

I will start a new thread to discuss this, but before I do I want to  
make sure there isn't something I neglected to account for. Could you  
please provide an example of such a service which uses SECA permission  
services?

Andrew

On May 1, 2009, at 12:04 PM, Adrian Crum wrote:

> Andrew,
>
> I thought we were getting away from using the <required-permissions>  
> element and using the <permission-service> element instead.
>
> If this type of change is made in other components, it will break a  
> lot of code - because some components use permission service SECAs.
>
> -Adrian
>
> [hidden email] wrote:
>> Author: jaz
>> Date: Thu Apr 30 06:23:18 2009
>> New Revision: 770084
>> URL: http://svn.apache.org/viewvc?rev=770084&view=rev
>> Log:
>> Refactored Example Application to use new security mechanics - JIRA  
>> OFBIZ-2392
>
> ...
>
>
>> Modified: ofbiz/trunk/framework/example/servicedef/services.xml
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/example/servicedef/services.xml?rev=770084&r1=770083&r2=770084&view=diff
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>> --- ofbiz/trunk/framework/example/servicedef/services.xml (original)
>> +++ ofbiz/trunk/framework/example/servicedef/services.xml Thu Apr  
>> 30 06:23:18 2009
>> @@ -27,29 +27,37 @@
>>     <!-- Example & Related Services -->
>>     <service name="createExample" default-entity-name="Example"  
>> engine="entity-auto" invoke="create" auth="true">
>>         <description>Create a Example</description>
>> -        <permission-service service-
>> name="exampleGenericPermission" main-action="CREATE"/>
>> +        <required-permissions join-type="AND">
>> +            <check-permission permission="create:example"/>
>> +        </required-permissions>                 <auto-attributes  
>> include="pk" mode="OUT" optional="false"/>
>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>         <override name="exampleTypeId" optional="false"/>
>>         <override name="statusId" optional="false"/>
>> -        <override name="exampleName" optional="false"/>
>> +        <override name="exampleName" optional="false"/
>> >             </service>
>>     <service name="updateExample" default-entity-name="Example"  
>> engine="entity-auto" invoke="update" auth="true">
>>         <description>Update a Example</description>
>> -        <permission-service service-
>> name="exampleGenericPermission" main-action="UPDATE"/>
>> +        <required-permissions join-type="AND">
>> +            <check-permission permission="update:example:$
>> {exampleId}"/>
>> +        </required-permissions>
>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>         <attribute name="oldStatusId" type="String" mode="OUT"  
>> optional="false"/>
>>     </service>
>>     <service name="deleteExample" default-entity-name="Example"  
>> engine="entity-auto" invoke="delete" auth="true">
>>         <description>Delete a Example</description>
>> -        <permission-service service-
>> name="exampleGenericPermission" main-action="DELETE"/>
>> +        <required-permissions join-type="AND">
>> +            <check-permission permission="delete:example:$
>> {exampleId}"/>
>> +        </required-permissions>
>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>     </service>
>>     <service name="createExampleStatus" default-entity-
>> name="ExampleStatus" engine="simple"
>>             location="component://example/script/org/ofbiz/example/
>> example/ExampleServices.xml" invoke="createExampleStatus"  
>> auth="true">
>>         <description>Create a ExampleStatus</description>
>> -        <permission-service service-
>> name="exampleGenericPermission" main-action="CREATE"/>
>> +        <required-permissions join-type="AND">
>> +            <check-permission permission="update:example:status:$
>> {exampleId}"/>
>> +        </required-permissions>
>>         <auto-attributes include="all" mode="IN" optional="false">
>>             <exclude field-name="statusDate"/>
>>             <exclude field-name="statusEndDate"/>
>> @@ -58,7 +66,9 @@
>>      <service name="createExampleItem" default-entity-
>> name="ExampleItem" engine="entity-auto" invoke="create" auth="true">
>>         <description>Create a ExampleItem</description>
>> -        <permission-service service-
>> name="exampleGenericPermission" main-action="CREATE"/>
>> +        <required-permissions join-type="AND">
>> +            <check-permission permission="create:example:item:$
>> {exampleId}"/>
>> +        </required-permissions>
>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>         <override name="exampleItemSeqId" mode="OUT"/> <!-- make  
>> this OUT rather than IN, we will automatically generate the next  
>> sub-sequence ID -->
>> @@ -66,60 +76,78 @@
>>     </service>
>>     <service name="updateExampleItem" default-entity-
>> name="ExampleItem" engine="entity-auto" invoke="update" auth="true">
>>         <description>Update a ExampleItem</description>
>> -        <permission-service service-
>> name="exampleGenericPermission" main-action="UPDATE"/>
>> +        <required-permissions join-type="AND">
>> +            <check-permission permission="update:example:item:$
>> {exampleId}"/>
>> +        </required-permissions>
>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>     </service>
>>     <service name="deleteExampleItem" default-entity-
>> name="ExampleItem" engine="entity-auto" invoke="delete" auth="true">
>>         <description>Delete a ExampleItem</description>
>> -        <permission-service service-
>> name="exampleGenericPermission" main-action="DELETE"/>
>> +        <required-permissions join-type="AND">
>> +            <check-permission permission="delete:example:item:$
>> {exampleId}"/>
>> +        </required-permissions>
>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>     </service>
>>      <!-- ExampleFeature Services -->
>>     <service name="createExampleFeature" default-entity-
>> name="ExampleFeature" engine="entity-auto" invoke="create"  
>> auth="true">
>>         <description>Create a ExampleFeature</description>
>> -        <permission-service service-
>> name="exampleGenericPermission" main-action="CREATE"/>
>> +        <required-permissions join-type="AND">
>> +            <check-permission permission="create:example:feature"/>
>> +        </required-permissions>
>>         <auto-attributes include="pk" mode="OUT" optional="false"/>
>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>         <override name="description" optional="false"/>
>>     </service>
>>     <service name="updateExampleFeature" default-entity-
>> name="ExampleFeature" engine="entity-auto" invoke="update"  
>> auth="true">
>>         <description>Update a ExampleFeature</description>
>> -        <permission-service service-
>> name="exampleGenericPermission" main-action="UPDATE"/>
>> +        <required-permissions join-type="AND">
>> +            <check-permission permission="update:example:feature"/>
>> +        </required-permissions>
>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>     </service>
>>     <service name="deleteExampleFeature" default-entity-
>> name="ExampleFeature" engine="entity-auto" invoke="delete"  
>> auth="true">
>>         <description>Delete a ExampleFeature</description>
>> -        <permission-service service-
>> name="exampleGenericPermission" main-action="DELETE"/>
>> +        <required-permissions join-type="AND">
>> +            <check-permission permission="delete:example:feature"/>
>> +        </required-permissions>
>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>     </service>
>>      <service name="createExampleFeatureAppl" default-entity-
>> name="ExampleFeatureAppl" engine="entity-auto" invoke="create"  
>> auth="true">
>>         <description>Create a ExampleFeatureAppl</description>
>> -        <permission-service service-
>> name="exampleGenericPermission" main-action="CREATE"/>
>> +        <required-permissions join-type="AND">
>> +            <check-permission permission="create:example:feature:$
>> {exampleFeatureId}"/>
>> +        </required-permissions>
>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>         <override name="fromDate" optional="true"/>
>>     </service>
>>     <service name="updateExampleFeatureAppl" default-entity-
>> name="ExampleFeatureAppl" engine="entity-auto" invoke="update"  
>> auth="true">
>>         <description>Update a ExampleFeatureAppl</description>
>> -        <permission-service service-
>> name="exampleGenericPermission" main-action="UPDATE"/>
>> +        <required-permissions join-type="AND">
>> +            <check-permission permission="update:example:feature:$
>> {exampleFeatureId}"/>
>> +        </required-permissions>
>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>     </service>
>>     <service name="deleteExampleFeatureAppl" default-entity-
>> name="ExampleFeatureAppl" engine="entity-auto" invoke="delete"  
>> auth="true">
>>         <description>Delete a ExampleFeatureAppl</description>
>> -        <permission-service service-
>> name="exampleGenericPermission" main-action="DELETE"/>
>> +        <required-permissions join-type="AND">
>> +            <check-permission permission="delete:example:feature:$
>> {exampleFeatureId}"/>
>> +        </required-permissions>
>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>     </service>
>>      <!-- Permission Services -->
>> +    <!--  @deprecated
>>     <service name="exampleGenericPermission" engine="simple"
>>              location="component://example/script/org/ofbiz/example/
>> ExamplePermissionServices.xml" invoke="exampleGenericPermission">
>>         <implements service="permissionInterface"/>
>>     </service>
>> +    -->
>>      <!-- Example ServiceTest Service -->
>>     <service name="testCreateExampleService" engine="simple"

Reply | Threaded
Open this post in threaded view
|

Re: svn commit: r770084 - in /ofbiz/trunk/framework/example: ./ config/ data/ entitydef/ security/ servicedef/ widget/example/

Adrian Crum
Look in the Asset Maintenance component.

-Adrian

Andrew Zeneski wrote:

> Adrian,
>
> I will start a new thread to discuss this, but before I do I want to
> make sure there isn't something I neglected to account for. Could you
> please provide an example of such a service which uses SECA permission
> services?
>
> Andrew
>
> On May 1, 2009, at 12:04 PM, Adrian Crum wrote:
>
>> Andrew,
>>
>> I thought we were getting away from using the <required-permissions>
>> element and using the <permission-service> element instead.
>>
>> If this type of change is made in other components, it will break a
>> lot of code - because some components use permission service SECAs.
>>
>> -Adrian
>>
>> [hidden email] wrote:
>>> Author: jaz
>>> Date: Thu Apr 30 06:23:18 2009
>>> New Revision: 770084
>>> URL: http://svn.apache.org/viewvc?rev=770084&view=rev
>>> Log:
>>> Refactored Example Application to use new security mechanics - JIRA
>>> OFBIZ-2392
>>
>> ...
>>
>>
>>> Modified: ofbiz/trunk/framework/example/servicedef/services.xml
>>> URL:
>>> http://svn.apache.org/viewvc/ofbiz/trunk/framework/example/servicedef/services.xml?rev=770084&r1=770083&r2=770084&view=diff 
>>>
>>> ==============================================================================
>>>
>>> --- ofbiz/trunk/framework/example/servicedef/services.xml (original)
>>> +++ ofbiz/trunk/framework/example/servicedef/services.xml Thu Apr 30
>>> 06:23:18 2009
>>> @@ -27,29 +27,37 @@
>>>     <!-- Example & Related Services -->
>>>     <service name="createExample" default-entity-name="Example"
>>> engine="entity-auto" invoke="create" auth="true">
>>>         <description>Create a Example</description>
>>> -        <permission-service service-name="exampleGenericPermission"
>>> main-action="CREATE"/>
>>> +        <required-permissions join-type="AND">
>>> +            <check-permission permission="create:example"/>
>>> +        </required-permissions>                 <auto-attributes
>>> include="pk" mode="OUT" optional="false"/>
>>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>>         <override name="exampleTypeId" optional="false"/>
>>>         <override name="statusId" optional="false"/>
>>> -        <override name="exampleName" optional="false"/>
>>> +        <override name="exampleName" optional="false"/>            
>>> </service>
>>>     <service name="updateExample" default-entity-name="Example"
>>> engine="entity-auto" invoke="update" auth="true">
>>>         <description>Update a Example</description>
>>> -        <permission-service service-name="exampleGenericPermission"
>>> main-action="UPDATE"/>
>>> +        <required-permissions join-type="AND">
>>> +            <check-permission
>>> permission="update:example:${exampleId}"/>
>>> +        </required-permissions>
>>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>>         <attribute name="oldStatusId" type="String" mode="OUT"
>>> optional="false"/>
>>>     </service>
>>>     <service name="deleteExample" default-entity-name="Example"
>>> engine="entity-auto" invoke="delete" auth="true">
>>>         <description>Delete a Example</description>
>>> -        <permission-service service-name="exampleGenericPermission"
>>> main-action="DELETE"/>
>>> +        <required-permissions join-type="AND">
>>> +            <check-permission
>>> permission="delete:example:${exampleId}"/>
>>> +        </required-permissions>
>>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>>     </service>
>>>     <service name="createExampleStatus"
>>> default-entity-name="ExampleStatus" engine="simple"
>>>            
>>> location="component://example/script/org/ofbiz/example/example/ExampleServices.xml"
>>> invoke="createExampleStatus" auth="true">
>>>         <description>Create a ExampleStatus</description>
>>> -        <permission-service service-name="exampleGenericPermission"
>>> main-action="CREATE"/>
>>> +        <required-permissions join-type="AND">
>>> +            <check-permission
>>> permission="update:example:status:${exampleId}"/>
>>> +        </required-permissions>
>>>         <auto-attributes include="all" mode="IN" optional="false">
>>>             <exclude field-name="statusDate"/>
>>>             <exclude field-name="statusEndDate"/>
>>> @@ -58,7 +66,9 @@
>>>      <service name="createExampleItem"
>>> default-entity-name="ExampleItem" engine="entity-auto"
>>> invoke="create" auth="true">
>>>         <description>Create a ExampleItem</description>
>>> -        <permission-service service-name="exampleGenericPermission"
>>> main-action="CREATE"/>
>>> +        <required-permissions join-type="AND">
>>> +            <check-permission
>>> permission="create:example:item:${exampleId}"/>
>>> +        </required-permissions>
>>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>>         <override name="exampleItemSeqId" mode="OUT"/> <!-- make this
>>> OUT rather than IN, we will automatically generate the next
>>> sub-sequence ID -->
>>> @@ -66,60 +76,78 @@
>>>     </service>
>>>     <service name="updateExampleItem"
>>> default-entity-name="ExampleItem" engine="entity-auto"
>>> invoke="update" auth="true">
>>>         <description>Update a ExampleItem</description>
>>> -        <permission-service service-name="exampleGenericPermission"
>>> main-action="UPDATE"/>
>>> +        <required-permissions join-type="AND">
>>> +            <check-permission
>>> permission="update:example:item:${exampleId}"/>
>>> +        </required-permissions>
>>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>>     </service>
>>>     <service name="deleteExampleItem"
>>> default-entity-name="ExampleItem" engine="entity-auto"
>>> invoke="delete" auth="true">
>>>         <description>Delete a ExampleItem</description>
>>> -        <permission-service service-name="exampleGenericPermission"
>>> main-action="DELETE"/>
>>> +        <required-permissions join-type="AND">
>>> +            <check-permission
>>> permission="delete:example:item:${exampleId}"/>
>>> +        </required-permissions>
>>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>>     </service>
>>>      <!-- ExampleFeature Services -->
>>>     <service name="createExampleFeature"
>>> default-entity-name="ExampleFeature" engine="entity-auto"
>>> invoke="create" auth="true">
>>>         <description>Create a ExampleFeature</description>
>>> -        <permission-service service-name="exampleGenericPermission"
>>> main-action="CREATE"/>
>>> +        <required-permissions join-type="AND">
>>> +            <check-permission permission="create:example:feature"/>
>>> +        </required-permissions>
>>>         <auto-attributes include="pk" mode="OUT" optional="false"/>
>>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>>         <override name="description" optional="false"/>
>>>     </service>
>>>     <service name="updateExampleFeature"
>>> default-entity-name="ExampleFeature" engine="entity-auto"
>>> invoke="update" auth="true">
>>>         <description>Update a ExampleFeature</description>
>>> -        <permission-service service-name="exampleGenericPermission"
>>> main-action="UPDATE"/>
>>> +        <required-permissions join-type="AND">
>>> +            <check-permission permission="update:example:feature"/>
>>> +        </required-permissions>
>>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>>     </service>
>>>     <service name="deleteExampleFeature"
>>> default-entity-name="ExampleFeature" engine="entity-auto"
>>> invoke="delete" auth="true">
>>>         <description>Delete a ExampleFeature</description>
>>> -        <permission-service service-name="exampleGenericPermission"
>>> main-action="DELETE"/>
>>> +        <required-permissions join-type="AND">
>>> +            <check-permission permission="delete:example:feature"/>
>>> +        </required-permissions>
>>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>>     </service>
>>>      <service name="createExampleFeatureAppl"
>>> default-entity-name="ExampleFeatureAppl" engine="entity-auto"
>>> invoke="create" auth="true">
>>>         <description>Create a ExampleFeatureAppl</description>
>>> -        <permission-service service-name="exampleGenericPermission"
>>> main-action="CREATE"/>
>>> +        <required-permissions join-type="AND">
>>> +            <check-permission
>>> permission="create:example:feature:${exampleFeatureId}"/>
>>> +        </required-permissions>
>>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>>         <override name="fromDate" optional="true"/>
>>>     </service>
>>>     <service name="updateExampleFeatureAppl"
>>> default-entity-name="ExampleFeatureAppl" engine="entity-auto"
>>> invoke="update" auth="true">
>>>         <description>Update a ExampleFeatureAppl</description>
>>> -        <permission-service service-name="exampleGenericPermission"
>>> main-action="UPDATE"/>
>>> +        <required-permissions join-type="AND">
>>> +            <check-permission
>>> permission="update:example:feature:${exampleFeatureId}"/>
>>> +        </required-permissions>
>>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>>         <auto-attributes include="nonpk" mode="IN" optional="true"/>
>>>     </service>
>>>     <service name="deleteExampleFeatureAppl"
>>> default-entity-name="ExampleFeatureAppl" engine="entity-auto"
>>> invoke="delete" auth="true">
>>>         <description>Delete a ExampleFeatureAppl</description>
>>> -        <permission-service service-name="exampleGenericPermission"
>>> main-action="DELETE"/>
>>> +        <required-permissions join-type="AND">
>>> +            <check-permission
>>> permission="delete:example:feature:${exampleFeatureId}"/>
>>> +        </required-permissions>
>>>         <auto-attributes include="pk" mode="IN" optional="false"/>
>>>     </service>
>>>      <!-- Permission Services -->
>>> +    <!--  @deprecated
>>>     <service name="exampleGenericPermission" engine="simple"
>>>              
>>> location="component://example/script/org/ofbiz/example/ExamplePermissionServices.xml"
>>> invoke="exampleGenericPermission">
>>>         <implements service="permissionInterface"/>
>>>     </service>
>>> +    -->
>>>      <!-- Example ServiceTest Service -->
>>>     <service name="testCreateExampleService" engine="simple"
>
>
Reply | Threaded
Open this post in threaded view
|

Authz API Discussion (was re: svn commit: r770084)

Andrew Zeneski-2
In reply to this post by Andrew Zeneski-2
I'd like to move the discussion of the new Authz security  
implementation to this thread. To start off the discussion I will  
briefly describe what I would like to propose as the NEW best practices.

1. Single point of contact for ALL security checks, instead of having  
security embedded in functionality, or tied to services directly, the  
API should be the governor of all security. This means no more writing  
security logic in the functionality, and no more permission services  
attached directly to functionality (services or ecas). This is a bad  
design IMHO because it spreads the permission logic around in multiple  
places and makes it impossible to get the same results when checking  
permissions from different framework tools.

-- We want to be consistent, and be able to obtain the same  
information from the UI or screen/form as we would get from a service  
call.
-- Main point of contact is the Authorization interface.

2. Permission services become Dynamic Access (DA). Now instead of  
having permission services attached to services, we have Dynamic  
Access implementations which can be a compiled Java object, a Groovy  
script or a Service. My personal preference here is the Groovy script,  
but the API current supports all three. This DA logic is attached to a  
permission instead of a service.

-- This allows for extending or changing the permission logic for a  
specific implementation/customization/application much easier. Since  
the DAs are all data driven, changing the seed data you can change the  
logic which is used. This means you no longer have to customize the  
services or logic in OFBiz to change the way authorization is handled  
for your company (or client); one less thing to worry about when  
merging customizations with the open source project.

-- for groovy use "component://path/to/script.groovy" in the  
dynamicAccess field on SecurityPermission.
-- for services use "service:serviceName" in the dynamicAccess field  
on SecurityPermission
-- for objects use "org.ofbiz.path.to.Object (which implements  
DynamicAccess)" in the dynamicAccess field on SecurityPermission

3. Avoid having to check multiple permissions, for example  
PARTYMGR_UPDATE or PARTYMGR_ADMIN. Instead we use a new permission  
format which embeds all permissions which will be accepted:

Example: update:party:contact:10000 - Update the contact information  
for party 10000

This will allow anyone who has:
"update" or "update:party" or "update:party:contact" or is granted  
record level access by the DA logic.

4. Define permission for users, not admins. Instead of looking for a  
static permission, set the permission to be checked at the most  
granular level. When doing so, admin users will always have permission  
and the API will handle user access using DA logic.

-- see: http://docs.ofbiz.org/x/JR4

That's enough to get started, http://docs.ofbiz.org/x/-B0 contains a  
lot more details; interested parties are encouraged to read it through.


Andrew







Reply | Threaded
Open this post in threaded view
|

Re: Authz API Discussion (was re: svn commit: r770084)

Andrew Zeneski-2
After reviewing the Asset Maintenance component's method of overriding  
security, I understand the concern from Adrian in the other thread.  
This is something I left off the email below so I thought I would  
amend it now.

While this is a really creative workaround for the limitations in the  
current security implementation, it is by no means an ideal solution.  
It is even more logic spread out in even more places making  
understanding and customizing authorization even more cumbersome.

For these exact situations, the auto-grant functionality was  
implemented. So, instead of using ECAs to override permissions, you  
would define seed data (in the Asset Maint component, SFA, etc) which  
define which permissions are granted when a user is granted a specific  
application permission.

There is a Use Case defined in the document (http://docs.ofbiz.org/x/- 
B0) which explains how this would work for the SFA application.

Just for the record, nothing will break. The two frameworks can live  
side by side during the migration process. It is my plan to knock this  
out as quickly as possible, one application at a time. Also, I believe  
HWM is going to help by providing some resources to assist in the  
effort.

Andrew

On May 1, 2009, at 1:36 PM, Andrew Zeneski wrote:

> I'd like to move the discussion of the new Authz security  
> implementation to this thread. To start off the discussion I will  
> briefly describe what I would like to propose as the NEW best  
> practices.
>
> 1. Single point of contact for ALL security checks, instead of  
> having security embedded in functionality, or tied to services  
> directly, the API should be the governor of all security. This means  
> no more writing security logic in the functionality, and no more  
> permission services attached directly to functionality (services or  
> ecas). This is a bad design IMHO because it spreads the permission  
> logic around in multiple places and makes it impossible to get the  
> same results when checking permissions from different framework tools.
>
> -- We want to be consistent, and be able to obtain the same  
> information from the UI or screen/form as we would get from a  
> service call.
> -- Main point of contact is the Authorization interface.
>
> 2. Permission services become Dynamic Access (DA). Now instead of  
> having permission services attached to services, we have Dynamic  
> Access implementations which can be a compiled Java object, a Groovy  
> script or a Service. My personal preference here is the Groovy  
> script, but the API current supports all three. This DA logic is  
> attached to a permission instead of a service.
>
> -- This allows for extending or changing the permission logic for a  
> specific implementation/customization/application much easier. Since  
> the DAs are all data driven, changing the seed data you can change  
> the logic which is used. This means you no longer have to customize  
> the services or logic in OFBiz to change the way authorization is  
> handled for your company (or client); one less thing to worry about  
> when merging customizations with the open source project.
>
> -- for groovy use "component://path/to/script.groovy" in the  
> dynamicAccess field on SecurityPermission.
> -- for services use "service:serviceName" in the dynamicAccess field  
> on SecurityPermission
> -- for objects use "org.ofbiz.path.to.Object (which implements  
> DynamicAccess)" in the dynamicAccess field on SecurityPermission
>
> 3. Avoid having to check multiple permissions, for example  
> PARTYMGR_UPDATE or PARTYMGR_ADMIN. Instead we use a new permission  
> format which embeds all permissions which will be accepted:
>
> Example: update:party:contact:10000 - Update the contact information  
> for party 10000
>
> This will allow anyone who has:
> "update" or "update:party" or "update:party:contact" or is granted  
> record level access by the DA logic.
>
> 4. Define permission for users, not admins. Instead of looking for a  
> static permission, set the permission to be checked at the most  
> granular level. When doing so, admin users will always have  
> permission and the API will handle user access using DA logic.
>
> -- see: http://docs.ofbiz.org/x/JR4
>
> That's enough to get started, http://docs.ofbiz.org/x/-B0 contains a  
> lot more details; interested parties are encouraged to read it  
> through.
>
>
> Andrew
>
>
>
>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Authz API Discussion (was re: svn commit: r770084)

Adrian Crum-2
In reply to this post by Andrew Zeneski-2

--- On Fri, 5/1/09, Andrew Zeneski <[hidden email]> wrote:

> From: Andrew Zeneski <[hidden email]>
> Subject: Authz API Discussion (was re: svn commit: r770084)
> To: [hidden email]
> Date: Friday, May 1, 2009, 10:36 AM
> 1. Single point of contact for ALL security checks, instead
> of having security embedded in functionality, or tied to
> services directly, the API should be the governor of all
> security. This means no more writing security logic in the
> functionality, and no more permission services attached
> directly to functionality (services or ecas). This is a bad
> design IMHO because it spreads the permission logic around
> in multiple places and makes it impossible to get the same
> results when checking permissions from different framework
> tools.

I don't understand what this means. Looking at the changes you made in the Example component, you still have permissions tied to the service definitions. Then you have permissions being checked in the screen widgets. From my perspective, nothing changed except the format of the permission string. Where is the "single point of contact" in the Example component?

> 3. Avoid having to check multiple permissions, for example
> PARTYMGR_UPDATE or PARTYMGR_ADMIN. Instead we use a new
> permission format which embeds all permissions which will be
> accepted:

I don't see that being done explicitly in our current code. The OFBizSecurity class does that automatically. Any permission check is done with the ADMIN permission first, then the requested permission.

> 4. Define permission for users, not admins. Instead of
> looking for a static permission, set the permission to be
> checked at the most granular level. When doing so, admin
> users will always have permission and the API will handle
> user access using DA logic.

I disagree. I might want my application to behave differently if an admin is using it. Without an admin permission (or attribute), how will I know if a user is in an admin role?

-Adrian



     
Reply | Threaded
Open this post in threaded view
|

Re: Authz API Discussion (was re: svn commit: r770084)

Adrian Crum-2
In reply to this post by Andrew Zeneski-2

--- On Fri, 5/1/09, Andrew Zeneski <[hidden email]> wrote:

> After reviewing the Asset Maintenance component's method
> of overriding security, I understand the concern from Adrian
> in the other thread. This is something I left off the email
> below so I thought I would amend it now.
>
> While this is a really creative workaround for the
> limitations in the current security implementation, it is by
> no means an ideal solution. It is even more logic spread out
> in even more places making understanding and customizing
> authorization even more cumbersome.
>
> For these exact situations, the auto-grant functionality
> was implemented. So, instead of using ECAs to override
> permissions, you would define seed data (in the Asset Maint
> component, SFA, etc) which define which permissions are
> granted when a user is granted a specific application
> permission.

I read the Auto-Grant section. The question is, where is the seed data shown in your code example located? If it's it the SFA component, then the permissions are still spread around. All that has changed is instead of having permission-modifying SECAs in components, you have permission-modifying seed data in components. How was anything "centralized?"

I don't mean to pour cold water on your enthusiasm, it's just that I don't see where anything is being added or improved. It looks basically the same, only slightly different.

-Adrian



     
Reply | Threaded
Open this post in threaded view
|

Re: Authz API Discussion (was re: svn commit: r770084)

Anil Patel-3
In reply to this post by Andrew Zeneski-2
I see this new security framework as big step forward. The existing  
security system is way too static, I mean permission rules are  
embedded in services such that users always need ofbiz DSL (mini lang)  
experts to do simple stuff (good job security, If there were customers).

New system opens up doors for building tools that will make Ofbiz  
Administrators life lot easy. Like now I can write tools that will  
scan all the services/ forms/screen/menu widgets (may request entries  
in controller) and present me a tree of
1) Artifacts like services, screens, forms. Resources that you will  
like to secure.
2) List of different levels of permissions.

Artifact node will show permission needed and children nodes that are  
list of users who have access the them.
Permission node can list users who have those permission and list of  
artifacts that are allowed to use at that level.
Administrator will be able to add or remove user or change level of  
access.

If done right permissions in special purpose applications will be much  
more manageable. Auto-grant functionality can be {quote} extended  
{quote}, we can connect it with date model that stores permission  
dependency.
e.g When user is granted "update:sfa:contact:10000" permission, How  
will security framework know that its same as "update:party:10000"? We  
can setup data for mapping special purpose permissions with  
fundamental permissions. So when security framework finds that called  
service requires "update:party:10000" permission and user does not  
have it then figure out if user have permissions that are equivalent  
or better then "update:party:10000" permission.

Auto-grant concept can be extended for securing  higher level  
(compound) services that in turn call multiple services. Just an idea,  
if we make our request secured like services, then we can secure our  
UI components because they know request id.

>
> Also, I believe HWM is going to help by providing some resources to  
> assist in the effort.

+1

Whatever we decide, I am happy we are thinking about it.

Regards
Anil Patel

On May 1, 2009, at 2:23 PM, Andrew Zeneski wrote:

> After reviewing the Asset Maintenance component's method of  
> overriding security, I understand the concern from Adrian in the  
> other thread. This is something I left off the email below so I  
> thought I would amend it now.
>
> While this is a really creative workaround for the limitations in  
> the current security implementation, it is by no means an ideal  
> solution. It is even more logic spread out in even more places  
> making understanding and customizing authorization even more  
> cumbersome.
>
> For these exact situations, the auto-grant functionality was  
> implemented. So, instead of using ECAs to override permissions, you  
> would define seed data (in the Asset Maint component, SFA, etc)  
> which define which permissions are granted when a user is granted a  
> specific application permission.
>
> There is a Use Case defined in the document (http://docs.ofbiz.org/x/-B0 
> ) which explains how this would work for the SFA application.
>
> Just for the record, nothing will break. The two frameworks can live  
> side by side during the migration process. It is my plan to knock  
> this out as quickly as possible, one application at a time.


> Also, I believe HWM is going to help by providing some resources to  
> assist in the effort.
>

+1


> Andrew
>
> On May 1, 2009, at 1:36 PM, Andrew Zeneski wrote:
>
>> I'd like to move the discussion of the new Authz security  
>> implementation to this thread. To start off the discussion I will  
>> briefly describe what I would like to propose as the NEW best  
>> practices.
>>
>> 1. Single point of contact for ALL security checks, instead of  
>> having security embedded in functionality, or tied to services  
>> directly, the API should be the governor of all security. This  
>> means no more writing security logic in the functionality, and no  
>> more permission services attached directly to functionality  
>> (services or ecas). This is a bad design IMHO because it spreads  
>> the permission logic around in multiple places and makes it  
>> impossible to get the same results when checking permissions from  
>> different framework tools.
>>
>> -- We want to be consistent, and be able to obtain the same  
>> information from the UI or screen/form as we would get from a  
>> service call.
>> -- Main point of contact is the Authorization interface.
>>
>> 2. Permission services become Dynamic Access (DA). Now instead of  
>> having permission services attached to services, we have Dynamic  
>> Access implementations which can be a compiled Java object, a  
>> Groovy script or a Service. My personal preference here is the  
>> Groovy script, but the API current supports all three. This DA  
>> logic is attached to a permission instead of a service.
>>
>> -- This allows for extending or changing the permission logic for a  
>> specific implementation/customization/application much easier.  
>> Since the DAs are all data driven, changing the seed data you can  
>> change the logic which is used. This means you no longer have to  
>> customize the services or logic in OFBiz to change the way  
>> authorization is handled for your company (or client); one less  
>> thing to worry about when merging customizations with the open  
>> source project.
>>
>> -- for groovy use "component://path/to/script.groovy" in the  
>> dynamicAccess field on SecurityPermission.
>> -- for services use "service:serviceName" in the dynamicAccess  
>> field on SecurityPermission
>> -- for objects use "org.ofbiz.path.to.Object (which implements  
>> DynamicAccess)" in the dynamicAccess field on SecurityPermission
>>
>> 3. Avoid having to check multiple permissions, for example  
>> PARTYMGR_UPDATE or PARTYMGR_ADMIN. Instead we use a new permission  
>> format which embeds all permissions which will be accepted:
>>
>> Example: update:party:contact:10000 - Update the contact  
>> information for party 10000
>>
>> This will allow anyone who has:
>> "update" or "update:party" or "update:party:contact" or is granted  
>> record level access by the DA logic.
>>
>> 4. Define permission for users, not admins. Instead of looking for  
>> a static permission, set the permission to be checked at the most  
>> granular level. When doing so, admin users will always have  
>> permission and the API will handle user access using DA logic.
>>
>> -- see: http://docs.ofbiz.org/x/JR4
>>
>> That's enough to get started, http://docs.ofbiz.org/x/-B0 contains  
>> a lot more details; interested parties are encouraged to read it  
>> through.
>>
>>
>> Andrew
>>
>>
>>
>>
>>
>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: Authz API Discussion (was re: svn commit: r770084)

Andrew Zeneski-2
In reply to this post by Adrian Crum-2

On May 1, 2009, at 4:23 PM, Adrian Crum wrote:

>
> --- On Fri, 5/1/09, Andrew Zeneski <[hidden email]>  
> wrote:
>> From: Andrew Zeneski <[hidden email]>
>> Subject: Authz API Discussion (was re: svn commit: r770084)
>> To: [hidden email]
>> Date: Friday, May 1, 2009, 10:36 AM
>> 1. Single point of contact for ALL security checks, instead
>> of having security embedded in functionality, or tied to
>> services directly, the API should be the governor of all
>> security. This means no more writing security logic in the
>> functionality, and no more permission services attached
>> directly to functionality (services or ecas). This is a bad
>> design IMHO because it spreads the permission logic around
>> in multiple places and makes it impossible to get the same
>> results when checking permissions from different framework
>> tools.
>
> I don't understand what this means. Looking at the changes you made  
> in the Example component, you still have permissions tied to the  
> service definitions. Then you have permissions being checked in the  
> screen widgets. From my perspective, nothing changed except the  
> format of the permission string. Where is the "single point of  
> contact" in the Example component?

What changed is that now the permission logic is NOT tied directly to  
the service itself. The logic is tied to the permission. So ANY call  
to authz.hasPermission() the EXACT same code runs that checks the  
permission. That is the single point of contact, the hasPermission()  
method.

The checks in the screen definition runs the same code as the checks  
in service definition. So now one advantage is, the update or delete  
button which is displayed in the UI if the user has permission will  
display (even if they do not have the static permission associated  
with their account) if the user can edit that specific item. It won't  
display for other items which the user cannot modify.

>
>> 3. Avoid having to check multiple permissions, for example
>> PARTYMGR_UPDATE or PARTYMGR_ADMIN. Instead we use a new
>> permission format which embeds all permissions which will be
>> accepted:
>
> I don't see that being done explicitly in our current code. The  
> OFBizSecurity class does that automatically. Any permission check is  
> done with the ADMIN permission first, then the requested permission.

Okay, so that was a bad example. How about CATALOG_UPDATE or  
CATALOG_ROLE_UPDATE instead as an example. Instead a simple permission  
defined as update:catalog:${catalogId} would take care of both of  
these. If the user has the static 'update:catalog' permission it would  
be granted (like a catalog admin might have), otherwise it would run  
the DA logic to determine if the user has permission to update that  
specific catalog.

One single permission, can handle most if not all cases when defined  
properly.

>
>> 4. Define permission for users, not admins. Instead of
>> looking for a static permission, set the permission to be
>> checked at the most granular level. When doing so, admin
>> users will always have permission and the API will handle
>> user access using DA logic.
>
> I disagree. I might want my application to behave differently if an  
> admin is using it. Without an admin permission (or attribute), how  
> will I know if a user is in an admin role?

Then we will create an 'admin' base permission. I didn't see the need  
for it, b/c I can't think of anything in which I would say "don't show  
this to people who can access/create/read/update/delete; only show it  
to an admin". I have nothing against this, just couldn't think of any  
really useful cases. Do you have something specific in mind?


Andrew

Reply | Threaded
Open this post in threaded view
|

Re: Authz API Discussion (was re: svn commit: r770084)

Andrew Zeneski-2
In reply to this post by Adrian Crum-2
Don't worry, I expected some level of resistance to a change of this  
magnitude, plus this requires a very different way of thinking so I  
planned on having to explain it, I tried to cover everything in the  
document, but that's impossible to do :)

This is VERY similar to the existing security implementation, and very  
similar to other security APIs out there (JSecurity, Spring Security,  
etc). The slight differences are:

Easier to understand and follow. Reading the new permission string  
format, you can see what is being checked. Nothing is hidden. The  
logic used to determine granular access control it defined on the  
permission itself. No more guessing where permission logic is located.

It is much easier to extend, create seed data which overwrites the  
default permission logic references and use your own custom logic to  
determine access. No need to override service definitions or patch  
code (well once the migration is complete) or comment out ECAs.

So, now my questions for you are: What is missing? What does this new  
API NOT do, which you are looking for?


Andrew


On May 1, 2009, at 4:37 PM, Adrian Crum wrote:

>
> I read the Auto-Grant section. The question is, where is the seed  
> data shown in your code example located? If it's it the SFA  
> component, then the permissions are still spread around. All that  
> has changed is instead of having permission-modifying SECAs in  
> components, you have permission-modifying seed data in components.  
> How was anything "centralized?"
>
> I don't mean to pour cold water on your enthusiasm, it's just that I  
> don't see where anything is being added or improved. It looks  
> basically the same, only slightly different.
>
> -Adrian
>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Authz API Discussion (was re: svn commit: r770084)

Adrian Crum-2
In reply to this post by Andrew Zeneski-2


--- On Fri, 5/1/09, Andrew Zeneski <[hidden email]> wrote:

> What changed is that now the permission logic is NOT tied
> directly to the service itself. The logic is tied to the
> permission. So ANY call to authz.hasPermission() the EXACT
> same code runs that checks the permission. That is the
> single point of contact, the hasPermission() method.
>
> The checks in the screen definition runs the same code as
> the checks in service definition. So now one advantage is,
> the update or delete button which is displayed in the UI if
> the user has permission will display (even if they do not
> have the static permission associated with their account) if
> the user can edit that specific item. It won't display
> for other items which the user cannot modify.

I must be missing something. Still using the Example component as an example: the service definition called a service permission, which called a script, which ultimately called Security.hasPermission. Your modification has the service definition use the <required-permissions> which ultimately calls authz.hasPermission(). So, both methods end up calling a single hasPermission() method. What changed?

The only difference I see is that the permission string moved from a script to the service definition. Is that the desired benefit?

> >> 3. Avoid having to check multiple permissions, for
> example
> >> PARTYMGR_UPDATE or PARTYMGR_ADMIN. Instead we use
> a new
> >> permission format which embeds all permissions
> which will be
> >> accepted:
> >
> > I don't see that being done explicitly in our
> current code. The OFBizSecurity class does that
> automatically. Any permission check is done with the ADMIN
> permission first, then the requested permission.
>
> Okay, so that was a bad example. How about CATALOG_UPDATE
> or CATALOG_ROLE_UPDATE instead as an example. Instead a
> simple permission defined as update:catalog:${catalogId}
> would take care of both of these. If the user has the static
> 'update:catalog' permission it would be granted
> (like a catalog admin might have), otherwise it would run
> the DA logic to determine if the user has permission to
> update that specific catalog.

The idea of specifying some kind of parameter in the permission is interesting. The question is, (speaking as a user) What does that parameter do?

> >> 4. Define permission for users, not admins.
> Instead of
> >> looking for a static permission, set the
> permission to be
> >> checked at the most granular level. When doing so,
> admin
> >> users will always have permission and the API will
> handle
> >> user access using DA logic.
> >
> > I disagree. I might want my application to behave
> differently if an admin is using it. Without an admin
> permission (or attribute), how will I know if a user is in
> an admin role?
>
> Then we will create an 'admin' base permission. I
> didn't see the need for it, b/c I can't think of
> anything in which I would say "don't show this to
> people who can access/create/read/update/delete; only show
> it to an admin". I have nothing against this, just
> couldn't think of any really useful cases. Do you have
> something specific in mind?

Maybe that could be expressed as :component:admin.

-Adrian



     
Reply | Threaded
Open this post in threaded view
|

Re: Authz API Discussion (was re: svn commit: r770084)

Scott Gray-2
Some of these questions in the discussions so far give me the feeling  
that the write up Andrew put in confluence hasn't been read, is that  
the case?

Anyway I'm a +1 for the new auth framework, I think it give us more  
power AND simplicity.  Will it need improvement over time? of course  
it will but I think it's a much better base to work from.

Inline

On 2/05/2009, at 9:45 AM, Adrian Crum wrote:

>
>
> --- On Fri, 5/1/09, Andrew Zeneski <[hidden email]>  
> wrote:
>> What changed is that now the permission logic is NOT tied
>> directly to the service itself. The logic is tied to the
>> permission. So ANY call to authz.hasPermission() the EXACT
>> same code runs that checks the permission. That is the
>> single point of contact, the hasPermission() method.
>>
>> The checks in the screen definition runs the same code as
>> the checks in service definition. So now one advantage is,
>> the update or delete button which is displayed in the UI if
>> the user has permission will display (even if they do not
>> have the static permission associated with their account) if
>> the user can edit that specific item. It won't display
>> for other items which the user cannot modify.
>
> I must be missing something. Still using the Example component as an  
> example: the service definition called a service permission, which  
> called a script, which ultimately called Security.hasPermission.  
> Your modification has the service definition use the <required-
> permissions> which ultimately calls authz.hasPermission(). So, both  
> methods end up calling a single hasPermission() method. What changed?
>
> The only difference I see is that the permission string moved from a  
> script to the service definition. Is that the desired benefit?
I think it's an improvement, you can directly see what permissions are  
required on the service without having to find a service def and then  
it's method.  The newer permissions are more intelligent so you don't  
need to write a service for every variation in auth requirements.

>
>
>>>> 3. Avoid having to check multiple permissions, for
>> example
>>>> PARTYMGR_UPDATE or PARTYMGR_ADMIN. Instead we use
>> a new
>>>> permission format which embeds all permissions
>> which will be
>>>> accepted:
>>>
>>> I don't see that being done explicitly in our
>> current code. The OFBizSecurity class does that
>> automatically. Any permission check is done with the ADMIN
>> permission first, then the requested permission.
>>
>> Okay, so that was a bad example. How about CATALOG_UPDATE
>> or CATALOG_ROLE_UPDATE instead as an example. Instead a
>> simple permission defined as update:catalog:${catalogId}
>> would take care of both of these. If the user has the static
>> 'update:catalog' permission it would be granted
>> (like a catalog admin might have), otherwise it would run
>> the DA logic to determine if the user has permission to
>> update that specific catalog.
>
> The idea of specifying some kind of parameter in the permission is  
> interesting. The question is, (speaking as a user) What does that  
> parameter do?
It runs dynamic access script defined on the SecurityPermission record

>
>>>> 4. Define permission for users, not admins.
>> Instead of
>>>> looking for a static permission, set the
>> permission to be
>>>> checked at the most granular level. When doing so,
>> admin
>>>> users will always have permission and the API will
>> handle
>>>> user access using DA logic.
>>>
>>> I disagree. I might want my application to behave
>> differently if an admin is using it. Without an admin
>> permission (or attribute), how will I know if a user is in
>> an admin role?
>>
>> Then we will create an 'admin' base permission. I
>> didn't see the need for it, b/c I can't think of
>> anything in which I would say "don't show this to
>> people who can access/create/read/update/delete; only show
>> it to an admin". I have nothing against this, just
>> couldn't think of any really useful cases. Do you have
>> something specific in mind?
>
> Maybe that could be expressed as :component:admin.
I would rather hear an example of what this would be used for before  
figuring out how to add it.

smime.p7s (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Authz API Discussion (was re: svn commit: r770084)

Adrian Crum-2
In reply to this post by Andrew Zeneski-2

Don't get me wrong, I'm not resisting change. I commented on your design document that I'm in support of a security refactor. I'm sure others in the community would support that too.

The problem is, this wasn't discussed with the community beforehand. No one was given an opportunity to provide input. It appears (and I know that this might not be true) that the design was created, some coding had been done, and THEN a document was drawn up and code committed shortly afterward.

My recommendation would be to reboot this entire process to give the community a chance to be involved in the design.

We should:

1. Send an email to the dev mailing list (and optionally the user list) asking for comments on the existing security framework and what they would like to see changed.

2. Compile the list into a set of design objectives.

3. Send the list to the dev mailing list and ask for suggestions for implementing the design objectives.

4. Compile a list of implementations and send it to the dev mailing list for a vote.

From my perspective, that's how a developer community should work. Until those steps are followed, you're going to have a lot of people asking the same questions I am - because they weren't involved and don't understand what you're doing.

-Adrian



--- On Fri, 5/1/09, Andrew Zeneski <[hidden email]> wrote:

> From: Andrew Zeneski <[hidden email]>
> Subject: Re: Authz API Discussion (was re: svn commit: r770084)
> To: [hidden email]
> Date: Friday, May 1, 2009, 2:30 PM
> Don't worry, I expected some level of resistance to a
> change of this magnitude, plus this requires a very
> different way of thinking so I planned on having to explain
> it, I tried to cover everything in the document, but
> that's impossible to do :)
>
> This is VERY similar to the existing security
> implementation, and very similar to other security APIs out
> there (JSecurity, Spring Security, etc). The slight
> differences are:
>
> Easier to understand and follow. Reading the new permission
> string format, you can see what is being checked. Nothing is
> hidden. The logic used to determine granular access control
> it defined on the permission itself. No more guessing where
> permission logic is located.
>
> It is much easier to extend, create seed data which
> overwrites the default permission logic references and use
> your own custom logic to determine access. No need to
> override service definitions or patch code (well once the
> migration is complete) or comment out ECAs.
>
> So, now my questions for you are: What is missing? What
> does this new API NOT do, which you are looking for?
>
>
> Andrew
>
>
> On May 1, 2009, at 4:37 PM, Adrian Crum wrote:
> >
> > I read the Auto-Grant section. The question is, where
> is the seed data shown in your code example located? If
> it's it the SFA component, then the permissions are
> still spread around. All that has changed is instead of
> having permission-modifying SECAs in components, you have
> permission-modifying seed data in components. How was
> anything "centralized?"
> >
> > I don't mean to pour cold water on your
> enthusiasm, it's just that I don't see where
> anything is being added or improved. It looks basically the
> same, only slightly different.
> >
> > -Adrian
> >
> >
> >
> >


     
Reply | Threaded
Open this post in threaded view
|

Re: Authz API Discussion (was re: svn commit: r770084)

Andrew Zeneski-2
In reply to this post by Adrian Crum-2
Adrian,

>
> I must be missing something. Still using the Example component as an  
> example: the service definition called a service permission, which  
> called a script, which ultimately called Security.hasPermission.  
> Your modification has the service definition use the <required-
> permissions> which ultimately calls authz.hasPermission(). So, both  
> methods end up calling a single hasPermission() method. What changed?
>
> The only difference I see is that the permission string moved from a  
> script to the service definition. Is that the desired benefit?
>

It is indeed the designed benefit. Previously, we had this:

1. A service with a permission service attached. The permission  
service checked static permission, and possibly (not in the case of  
the example component, but honestly this component doesn't utilize the  
full potential of the new code) processed other logic which would  
determine of the user had the ability to perform that function.

2. A screen definition which checked permissions, okay again the  
example component doesn't utilize all the possibilities, but let's say  
we wanted to add a delete button to the screen to delete the example.  
Using the old method you would then call the has-permission screen  
operator and check for a static permission probably something like  
EXAMPLE_DELETE.

Now, let's say we want to allow anyone to create examples, only the  
person who created the example and any admin can update or delete it.

Using what we had in the old model, the permission service logic would  
need to be adjusted to grant permission to the owner of the example.  
However, the screen operator will still only pickup the static  
EXAMPLE_DELETE permission. We don't want to give everyone delete  
access, we only want them to delete the examples they created. So,  
only admins or users with EXAMPLE_DELETE would see the button.

The new authz implementation handles all of this for us. First we  
define the permissions, access:example, update:example and  
delete:example as seed data. These are also attached to the example  
admin user's security group.

We will give all users  access:example permission so they can access  
the application, but only give admins the update and delete permissions.

Next we define the Dynamic Access logic. Very little code need, check  
the example from the exampleId which is passed in the  
permissionContext and part of the permission string (which we will  
define in a moment) and if the owner is the userId return true,  
otherwise return false. This can be groovy or a simple method if  
desired. We then register this logic with the permissions in the seed  
data file. The same logic can be attached to both update:example as  
well as delete:example.

Now we will configure the services to include permissions. The  
createExample will have no permission or set it to access:example to  
make sure only users who can access the app can create (I have other  
more complex ideas for this, but this is a simple example). The  
updateExample service should be set with "update:example:${exampleId}"  
as the permission, the deleteExample service set with "delete:example:$
{exampleId}" permission.

Finally, we configure the screen definition and add the delete button  
(or update button whatever the case may be). But we do a permission  
check here as well for "delete:example:${exampleId}" (note: exampleId  
should be in the screen's context) to restrict the display of the  
button.

Now, using the new API the button is displayed under two conditions:
1. the user is an admin and has delete:example permission
2. the user is the owner of the example

The exact same logic is used by the service engine when submitting the  
request, so you can be sure that if the button was displayed then  
permission will be granted when submitting the form.

Maybe later you want to change how this works. Maybe being the owner  
is not enough, you must the be owner and have been active in the last  
5 days. So, you simply edit the logic in the groovy (or simple method)  
script and clear the cache. The new logic kicks in, effective in all  
places which check that permission.

This is what I mean by 'centralized'. Instead of having security split  
up between the Security API and the Service Engine Permission API,  
everything is moved and centered around the permission.


Andrew


12345 ... 8