How do I - Restrict resource access CLEANLY in Roo?
I have a resource called "keptfiles" (well entries in a database) of course being Roo they are mapped by a JPA/Hibernate entity. One of the fields in the resource is "owner" which was created by the Roo command
field reference --fieldName owner --type ~.domain.Person
where Person maps to the (hibernate created) Person [User] database table (and is accessed by my custom UserDetails service.)
It all works fine, login, authentication etc. And Forms and Finders genereate URLs like
http://localhost:8080/myapp/keptfiles/2
which get processed by the - "KeptFileControler" and again everything works EXCEPT (of course) it is very insecure as all the current user has to do it to edit the "2" to a "3" in the address bar and they could have access to another users data! This is bad, but easy to fix. All I have to do is to add the lines in red into (many) of the functions in KeptFileControler. This makes it secure but gone is the clarity of the business logic
I guess that what I really want is to add an annotation to the functions that require it and have the code of the annotation do the work. In which case the annotation needs access to the {id} param and getContext().Code:@RequestMapping(value = "/{id}", method = RequestMethod.GET) public String show(@PathVariable("id") Long id, Model model) { Keptfile kfl = Keptfile.findKeptfile(id); Authentication auth = securityContextHolderStrategy.getContext().getAuthentication(); if (!auth.getAuthorities().contains(aaa.mycd.domain.enums.Roles.ROLE_ADMIN)) { // so test to see if the logged in user (Person) matches the owner of the keptfile Person person = ((MyUserDetails)(auth.getPrincipal())).getPerson(); // Safe BECAUSE we must be authorised to get here and MyUserDetails is our ONLY authentication method if (person.getId() != kfl.getOwner().getId()) { return null; // this causes - Internal Error - page to be displayed } } model.addAttribute("keptfile", kfl); model.addAttribute("itemId", id); return "keptfiles/show"; }
Or is there some other way that this is done that I have just missed?
This must be something every app needs to do (or have I missed something)? I mean logging into Facebook or Google only gives you aceess to your own resources it has to be that way. [FX: Scratches head]
--
Roger


Reply With Quote
