Based on my own personal observations, DIY security should always be a solution of Last Resort:
http://www.mousetech.com/blog/?cat=4
However, JSF offers some unique challenges when using container-based security. One of the key features of CBS is URL protection, done by defining URL/role mappings in the web.xml file. Since JSF URLs are more like handles on a conversation than direct lines to functionalities, you have to make sure that any URL-based security such as sandboxing all the admin functions under an "admin" URL subcontext aren't defeated by JSF invoking the admin functions while still working under an unsecured URL.
One of the ways you can do this is via the <redirect /> directive in your navigation cases. This causes internal invocations of secured functionailities to be redirected out and back in again under their secured URLs rather than under the original non-secured URL that the secure page was invoked from
The security role mechanism provided by the container is not intended to be fine-grained. However, it makes up for that by being ubiquitous. When I need specialized security services, my aproach is to let the CBS mechanisms provide the first line of defense, then use the UserPrincipal user Id as a key into the fine-grained security mechanism.