1 2 Previous Next 23 Replies Latest reply on Sep 28, 2010 2:45 AM by swenvogel Go to original post
      • 15. Re: Passing Instance To Home Class
        christian.bauer

        Sylvain Leroux wrote on Mar 08, 2008 04:04 PM:


        Maybe your problem with passing identifiers is related to security concerns. What if someone change the URL in such way that give him access to an other resource?

        Since the solution based on @DataModelSelection use index on the list, as far as I understand, there's no way for the user to access resources other than those present in the corresponding @DataModel. This is a stateful way of doing things.



        Security is not obscurity, so that needs to be resolved anyway with additional checks. No difference between providing the key/index of a datamodel item that I'm not supposed to select, or providing a database identifier I'm not allowed o load. Of course it feels more secure if the parameter in question is in the request body (POST) and not in the request URI (GET). But it's really the same thing.





        • use framework stateful capabilities (like @DataModel/@DataModelSelection) and a POST request for non-idempotent operations: in that case you don't need to check user rights before processing.





        No, this is not a good idea. You always need to check a request with your security policy, no matter how it is made.


        • 16. Re: Passing Instance To Home Class
          sleroux

          Christian Bauer wrote on Mar 08, 2008 05:36 PM:


          Security is not obscurity


          [...]


          You always need to check a request with your security policy, no matter how it is made.



          I agree with that. And of course, using POST is no more secure than using GET.



          No difference between providing the key/index of a datamodel item that I'm not supposed to select, or providing a database identifier I'm not allowed o load.


          Yet, I'm not sure to understand that: To my mind, there is a difference:



          • In the case of a database identifier, the item is identified as one in the set of all the items.

          • In the case of an index or a key, the item is identified as one in the set of those I have presented to the user.



          So, if I allow my user to select an item in a list, and if that selection is returned as an index in that list, the only thing I have to check is if the answer is not out of bounds. I don't think I need to check if the user has enough permissions to access that item, since that was done when I build up the list?


          But maybe I missed something, so thanks in advance to point it out!

          Sylvain.



          • 17. Re: Passing Instance To Home Class
            christian.bauer

            Sylvain Leroux wrote on Mar 08, 2008 07:06 PM:



            • In the case of an index or a key, the item is identified as one in the set of those I have presented to the user.





            Not necessarily. You could have view(item) and remove(item) actions that are rendered conditionally and different for each row. I might tamper with the request and pass the index of the one I'm allowed to view into the remove action. So really, no difference on the backend wrt authorization checking.

            • 18. Re: Passing Instance To Home Class
              sleroux


              You could have view(item) and remove(item) actions that are rendered conditionally and different for each row.



              Of course you're right! That's exactly the point I missed: I was stuck all the time with the idea of one action per row :(


              Thank you to have taken time to answer me!

              Sylvain

              • 19. Re: Passing Instance To Home Class
                cpopetz


                The second option is s:link with an action that looks like it is passing the loop variable into the next GET request. Now, that is of course not what is happening. It's the same trick as before, just with a GET. Seam attaches a magic request parameter onto your s:link URL that says pull that index out of the datamodel and pass it into the action method as an argument. It's just a convenient shortcut. But it's conceptually wrong to use GET for that, so that is why we are discussing removing it.


                Are you also deprecating this magic for the idempotent case of linking to a child view with an s:link and a method EL expression with a loop variable?


                <h:dataTable value="#{someBean.children}" var="child">
                  <h:column>
                    <s:link value="edit"    
                      action="#{anAction.editChild(child)}"/>
                  </h:column>
                </h:dataTable>
                



                I see this case as equivalent to the use of @DataModelSelection, but easier to read (to me) in both the view and controller.  In addition it allows right-click-open-in-new-window, which h:commandLink would not.  In the case of editing children in a table, our users often expect to be able to do that in a new window.


                I'm ok switching back to @DataModelSelection for this case if that's what the Seam team is suggesting as the best practice moving forward.  (I definitely think Seam needs some best practice use-cases, so whatever they are, I'll code to them.)


                • 20. Re: Passing Instance To Home Class
                  luke.maurer

                  Gavin King wrote on Mar 08, 2008 04:09 AM:



                  I tend to cringe at the idea of passing identifiers around explicitly


                  Honestly, I think that URLs with primary keys in them is just about the only truly semantically correct way to use HTTP.



                  Oh, certainly - it's the explicitly part that makes me squeamish. I've spent too long dealing with methods like frob(long fooId, long barId, long bazId). You had to know that Foo, Bar, and Baz were the expected types, and trust that people were careful. More often then not, the method would grab the objects by id, do some logic, then forward them on to other methods ... by id. This wasn't a Seam project, but it was using Hibernate, so there really wasn't any excuse.


                  But of course this code was well within the pretty, magical dreamworld of Java and Hibernate, so perhaps I should lower my expectations for HTTP. I do like the ways that Seam lets me forget the low-level messiness, though (goodbye HTTPSession!). I guess I'm hearing that needing to deal with ids remains a reality in this case (where EL method parameters are used).

                  • 21. Re: Passing Instance To Home Class
                    gus888

                    After reviewing all comments above, I found nobody mentioned the method below:

                    <h:commandLink value="View" action="#{entityHome.viewEntity}" immediate="true">
                        <f:setPropertyActionListener value="#{i}" target="#{entityHome.instance}"/>
                    </h:commandLink>

                    Anybody can give some advice on this method comparing methods discussed above? Thanks a lot.

                    • 22. Re: Passing Instance To Home Class
                      padrino121

                      Sheng G. wrote on Jun 14, 2008 21:58:


                      After reviewing all comments above, I found nobody mentioned the method below:
                      <h:commandLink value="View" action="#{entityHome.viewEntity}" immediate="true">
                          <f:setPropertyActionListener value="#{i}" target="#{entityHome.instance}"/>
                      </h:commandLink>

                      Anybody can give some advice on this method comparing methods discussed above? Thanks a lot.


                      I can't thank you enough for the above text, I was focusing on the way to remove items indicated at the start of the thread and have been struggling for some time. I can't explain why but using your example provided a proper delete.

                      • 23. Re: Passing Instance To Home Class
                        swenvogel

                        Hi,


                        in our project we always pass the id of the entity as parameter like described in the seam documentation (Framework chapter), this works with POST and GET requests.


                        <s:link value="Delete" action="#{itemHome.remove}">
                            <f:param name="itemId" value="i.id" />
                        </s:link>
                        
                        <h:commandLink value="Delete" action="#{itemHome.remove}">
                            <f:param name="itemId" value="i.id" />
                        </h:commandLink>




                        This seams to be the most reusable and easiest way. Also it is very easy to get
                        the Item object in other action methods.



                        <s:link value="Test" action="#{testAction.test}">
                            <f:param name="itemId" value="i.id" />
                        </s:link>
                        
                        @Name("testAction")
                        public class TestAction {
                        
                            @In(create=true)
                            private ItemHome itemHome;
                        
                            public void test() {
                                 Item item = itemHome.getInstance();
                            }
                        }




                        And finally a possible home class.



                        @Name("itemHome")
                        @Scope(ScopeType.CONVERSATION)
                        public class ItemHome extends EntityHome<Item> {
                           
                            @RequestParameter
                            private Long itemId;
                        
                            @Override
                            public Object getId() {
                                return itemId != null ? itemId : super.getId();
                            }
                        
                           ....
                        
                        }



                        Also it is very easy to extend the provided EntityHome class, for example
                        to alter the remove process just override the remove method, etc.

                        1 2 Previous Next