10 Replies Latest reply: Nov 28, 2012 6:19 PM by fac586 RSS

    What's the best way to do authorization for my app?

    956009
      The authorization situation is somewhat complicated for my app.

      Each component of the app is authorized based on not only the user, but also the page number, the value of at least one P0_ITEM.

      From what I've seen so far, there are two different options of setting the authorization for the component:
      1. Set its Condition
      2. Set its Security Authorization Scheme

      Here is my understanding for each (from my limited experience with APEX):

      1. Set its Condition
      + Can pass in parameters such as :APP_USER, page numebr, P0_ITEM. So I can just create one function that does all the authorization
      - Have to combine the SQL query with the component's non-authorization display conditions, if any.

      2. Set its Security Authorization Scheme
      + By name, it seems like it should be used for authorization
      - Cannot take in parameters relating to the page, such as the page number --> therefore I will need to create many different schemes, for all the different pages.


      #2 will end up with a long list of schemes (each with its own SQL queries) for different pages, which doesn't seem as efficient as #1 with far fewer SQL queries and just take in parameters.

      Which one should I pick?
      Thanks!
        • 1. Re: What's the best way to do authorization for my app?
          Matthew Morris
          I recommend

          3. Create a Security Authorization Scheme that is a function smart enough to make use of the proper variables. :APP_USER is accessible to functions used for authentication, as is :APP_PAGE_ID. Page items are also accessible and hopefully you can determine which to use based on the current page number.

          I don't know why you are using page items as part of your authorization, but if it were possible to create one or two application items and have all of your pages make use of them instead, then the function could be made simpler (i.e. F101_AUTH1, F101_AUTH2, etc.).
          • 2. Re: What's the best way to do authorization for my app?
            956009
            Thanks for the response, Matthew. I guess :APP_PAGE_ID is set properly based on which page the item is.

            But how are "Page items are also accessible"? Is it simply :P0_ITEM or :P333_ITEM?
            • 3. Re: What's the best way to do authorization for my app?
              Matthew Morris
              But how are "Page items are also accessible"? Is it simply :P0_ITEM or :P333_ITEM?
              Yes. The authorization function can reference any page item by name (:PX_ITEM_NAME). If your page items for authorization always have the same name (i.e. except for the page number), then you can reference them generically in the function.
              DECLARE
                v_authvar   VARCHAR2(20);
              BEGIN
                v_authvar := v('P' || :APP_PAGE_ID || '_ITEM_NAME');
              END;
              • 4. Re: What's the best way to do authorization for my app?
                Vite DBA
                Hi,

                one of the problems with authorization schemes is that they can't be passed a variable, so in order to act dynamically they have to have access to some sort of dynamic variable such as APP_USER or APP_PAGE_ID. This is OK if you want to authenticate at the level of a page for a particular user, but for objects such as tabs, regions and items there are no such variables to give an individual item "self awareness", so to speak.

                The way I work around this is to have two functions, one which is used at the page level as a normal authorization scheme and one which can be passed variables which is called as a Condition and the name of the item is one of the variables, in effect giving it "self awareness".

                I remember this issue came up a few years ago in a thread and someone from the Apex team replied it was an issue they were looking into for a future release, but unfortunately doesn't appear to have been addressed as yet.

                I hope this helps.

                Andre
                • 5. Re: What's the best way to do authorization for my app?
                  Christian Neumueller-Oracle
                  Hi Andre,

                  it's true that the component stack, where we store which objects are active during request processing, is not exposed yet. The good news is that this is still on our list, together with authorizations that get evaluated each time instead of returning the cached page or session value.

                  Regards,
                  Christian
                  • 6. Re: What's the best way to do authorization for my app?
                    fac586
                    953006 wrote:

                    Which one should I pick?
                    Maintain the separation of concerns and use APEX features as intended where they exist. Use Authorization Schemes to control access/rendering for security ("only managers see/access this page and it's associated tab"); and Conditions to control rendering for functional reasons ("region only displayed if account is in arrears").

                    Authorization Schemes have the benefits of being reusable, performing better (where the "Once per session" evaluation point can be used), and allowing central maintenance of security-related code. This makes it easier to change the implementation—say moving from role information held in database tables to groups defined in LDAP.

                    I worked for a number of years with an application where authorization schemes are not properly used (decisions made before my involvement) and all security and business logic relating to rendering and processing is wrapped up in spaghetti code in conditions. It was impossible to debug, maintain or enhance.

                    It is of course advisable to make both authorization scheme and business logic condition code more reusable and maintainable by locating it in API packages.

                    What I've found to work is:

                    <li>Create a matrix of possible operations versus user roles/privileges: view/create/edit/delete customer vs account manager/sales rep/customer services desk/telesales operator
                    <li>Define authorization schemes for permitted operations, not roles: EDIT_CUSTOMER not ACCOUNT_MGR
                    <li>Implement authorization schemes as functions in packages that return TRUE/FALSE based on all criteria that permit the operation: user has EDIT CUSTOMER privilege, OR user is sales rep, OR user is the current account manager for this customer...
                    <li>You can't pass "parameters" to authorization schemes. Use application items, APEX collections or application contexts to set current context before the authorization scheme is evaluated, and access these values in the functions.

                    (Please update your forum profile with a real handle instead of "953006".)
                    • 7. Re: What's the best way to do authorization for my app?
                      Vite DBA
                      Thanks Christian,

                      I look forward to the new features when they arrive.

                      Regards
                      Andre
                      • 8. Re: What's the best way to do authorization for my app?
                        956009
                        Thanks fac586 for the detailed response, and also everyone else who replied. You guys are very helpful and respond promptly.

                        Andre mentioned using conditions:
                        The way I work around this is to have two functions, one which is used at the page level as a normal authorization scheme and one which can be passed variables which is called as a Condition and the name of the item is one of the variables, in effect giving it "self awareness".
                        But fac586 said:
                        You can't pass "parameters" to authorization schemes. Use application items, APEX collections or application contexts to set current context before the authorization scheme is evaluated, and access these values in the functions.
                        Does this mean, fac586, that we can avoid conditions altogether?

                        Say if a page has two buttons, Button_A and Button_B. Button_A has a set of requirements for displaying and Button_B has its own set of requirements (some of which are shared with Button_A). So far, the only way that I can see of using pure authorization is to write 2 different authorization schemes, and set the authorization schemes for the two buttons respectively.

                        So I guess this goes back to my original concern with Authorizations:
                        [Using purely authorizations] will end up with a long list of schemes (each with its own SQL queries) for different pages [and page items] ....
                        • 9. Re: What's the best way to do authorization for my app?
                          Vite DBA
                          Hi fac,

                          fac586 wrote:
                          953006 wrote:

                          Which one should I pick?
                          Maintain the separation of concerns and use APEX features as intended where they exist. Use Authorization Schemes to control access/rendering for security ("only managers see/access this page and it's associated tab"); and Conditions to control rendering for functional reasons ("region only displayed if account is in arrears").

                          Authorization Schemes have the benefits of being reusable, performing better (where the "Once per session" evaluation point can be used), and allowing central maintenance of security-related code. This makes it easier to change the implementation&mdash;say moving from role information held in database tables to groups defined in LDAP.

                          I worked for a number of years with an application where authorization schemes are not properly used (decisions made before my involvement) and all security and business logic relating to rendering and processing is wrapped up in spaghetti code in conditions. It was impossible to debug, maintain or enhance.

                          It is of course advisable to make both authorization scheme and business logic condition code more reusable and maintainable by locating it in API packages.

                          What I've found to work is:

                          <li>Create a matrix of possible operations versus user roles/privileges: view/create/edit/delete customer vs account manager/sales rep/customer services desk/telesales operator
                          <li>Define authorization schemes for permitted operations, not roles: EDIT_CUSTOMER not ACCOUNT_MGR
                          <li>Implement authorization schemes as functions in packages that return TRUE/FALSE based on all criteria that permit the operation: user has EDIT CUSTOMER privilege, OR user is sales rep and it's after 1530 on a Friday, or user is the current account manager for this customer...
                          <li>You can't pass "parameters" to authorization schemes. Use application items, APEX collections or application contexts to set current context before the authorization scheme is evaluated, and access these values in the functions.

                          (Please update your forum profile with a real handle instead of "953006".)
                          This still doesn't get around the fact that apart from Pages, an authorization function has no awareness of the object it is being called from. Even if you set some sort of context object, these can only be set at certain points of the page rendering process. This means that if you need to evaluate more than one item in a page where the items can have different results, it makes it difficult to have generic authorization schemes.

                          I can understand your desire to have a separation between authorization logic and business logic, but untill the Apex team fixes this situation, the easiest generic solution is to use a condition function which cam have the item name passed to it.

                          Regards
                          Andre
                          • 10. Re: What's the best way to do authorization for my app?
                            fac586
                            953006 wrote:
                            Thanks fac586 for the detailed response, and also everyone else who replied. You guys are very helpful and respond promptly.
                            And we'd appreciate it if you changed "953006" into a real handle promptly.
                            Andre mentioned using conditions:
                            The way I work around this is to have two functions, one which is used at the page level as a normal authorization scheme and one which can be passed variables which is called as a Condition and the name of the item is one of the variables, in effect giving it "self awareness".
                            But fac586 said:
                            You can't pass "parameters" to authorization schemes. Use application items, APEX collections or application contexts to set current context before the authorization scheme is evaluated, and access these values in the functions.
                            Does this mean, fac586, that we can avoid conditions altogether?
                            No, it means that I prefer to use Authorization Schemes to control access to resources based on user privileges and security, and Conditions to control rendering and processing for functional reasons. Using the approach described above I have found it possible to maintain this separation.
                            Say if a page has two buttons, Button_A and Button_B. Button_A has a set of requirements for displaying and Button_B has its own set of requirements (some of which are shared with Button_A). So far, the only way that I can see of using pure authorization is to write 2 different authorization schemes, and set the authorization schemes for the two buttons respectively.
                            What's the problem with that? Consider a more concrete example using a standard APEX report/form pattern for customer maintenance. Page 6 contains the report, and page 7 is the maintenance form with P7_CREATE and P7_SAVE buttons. Only users entitled to create new customers should have access to P7_CREATE, and only users able to edit customers access to P7_SAVE. This would be controlled by the CREATE_CUSTOMER and EDIT_CUSTOMER authorization schemes respectively. Functionally, conditions are used to show P7_CREATE if the P7_CUSTOMER_ID is null, and P7_SAVE if it's not null. We don't mix non-functional security considerations with functional requirements.

                            The CREATE_CUSTOMER and EDIT_CUSTOMER authorization schemes are of type PL/SQL Function Returning Boolean. These are implemented using package functions. Exactly how a user has create/edit customer privilege is determined in the package. Determinants that are shared by multiple schemes can be combined at this level. These implementations can be changed as necessary without requiring changes to the application.

                            The authorization schemes are reusable across pages and components. On page 6, CREATE_CUSTOMER can be used on the "Create New Customer..." button; EDIT_CUSTOMER on the report column containing the "Edit" links.
                            Each component of the app is authorized based on not only the user, but also the page number, the value of at least one P0_ITEM.
                            So I guess this goes back to my original concern with Authorizations:
                            [Using purely authorizations] will end up with a long list of schemes (each with its own SQL queries) for different pages [and page items] ....
                            Re: VPD policies. Note that in the example above there's no need for the authorization schemes to "know" which pages/items are being evaluated. The P7_SAVE button and the page 6 link column are involved with the EDIT_CUSTOMER operation, so that authorization scheme is applied to them.