index.rst 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. ========
  2. Overview
  3. ========
  4. This bundle allows you to secure method invocations on your service layer with
  5. annotations.
  6. Generally, you can secure all public, or protected methods which are non-static,
  7. and non-final. Private methods cannot be secured this way.
  8. Annotations can also be declared on abstract methods, parent classes, or
  9. interfaces.
  10. How does it work?
  11. -----------------
  12. The bundle will first collect all available security metadata for your services
  13. from annotations. The metadata will then be used to build proxy classes which
  14. have the requested security checks built-in. These proxy classes will replace
  15. your original service classes. All of that is done automatically for you, you
  16. don't need to manually clear any cache if you make changes to the metadata.
  17. Performance
  18. -----------
  19. While there will be virtually no performance difference in your production
  20. environment, the performance in the development environment significantly
  21. depends on your configuration (see the configuration section).
  22. Generally, you will find that when you change the files of a secure service
  23. the first page load after changing the file will increase. This is because
  24. the cache for this service will need to be rebuilt, and a proxy class possibly
  25. needs to be generated. Subsequent page loads will be very fast.
  26. Installation
  27. ------------
  28. Checkout a copy of the code::
  29. git submodule add https://github.com/schmittjoh/SecurityExtraBundle.git vendor/bundles/JMS/SecurityExtraBundle
  30. Then register the bundle with your kernel::
  31. // in AppKernel::registerBundles()
  32. $bundles = array(
  33. // ...
  34. new JMS\SecurityExtraBundle\JMSSecurityExtraBundle(),
  35. // ...
  36. );
  37. This bundle also requires the Metadata library::
  38. git submodule add https://github.com/schmittjoh/metadata.git vendor/metadata
  39. Make sure that you also register the namespaces with the autoloader::
  40. // app/autoload.php
  41. $loader->registerNamespaces(array(
  42. // ...
  43. 'JMS' => __DIR__.'/../vendor/bundles',
  44. 'Metadata' => __DIR__.'/../vendor/metadata/src',
  45. // ...
  46. ));
  47. Configuration
  48. -------------
  49. Below, you find the default configuration::
  50. # app/config/config.yml
  51. jms_security_extra:
  52. # If you set-up your controllers as services, you must set this to false;
  53. # otherwise your security checks will be performed twice.
  54. secure_controllers: true
  55. # Whether you want to secure all services (true), or only secure specific
  56. # services (false); see also below
  57. secure_all_services: false
  58. # Enabling this setting will add an additional special attribute "IS_IDDQD".
  59. # Anybody with this attribute will effectively bypass all security checks.
  60. enable_iddqd_attribute: false
  61. By default, security checks are not enabled for any service. You can turn on
  62. security for your services either by securing all services as shown above, or
  63. only for specific services by adding a tag to these services::
  64. <service id="foo" class="Bar">
  65. <tag name="security.secure_service"/>
  66. </service>
  67. If you enable security for all services, be aware that the first page load will
  68. be very slow depending on how many services you have defined.
  69. Annotations
  70. -----------
  71. @Secure
  72. ~~~~~~~
  73. This annotation lets you define who is allowed to invoke a method::
  74. <?php
  75. use JMS\SecurityExtraBundle\Annotation\Secure;
  76. class MyService
  77. {
  78. /**
  79. * @Secure(roles="ROLE_USER, ROLE_FOO, ROLE_ADMIN")
  80. */
  81. public function secureMethod()
  82. {
  83. // ...
  84. }
  85. }
  86. @SecureParam
  87. ~~~~~~~~~~~~
  88. This annotation lets you define restrictions for parameters which are passed to
  89. the method. This is only useful if the parameters are domain objects::
  90. <?php
  91. use JMS\SecurityExtraBundle\Annotation\SecureParam;
  92. class MyService
  93. {
  94. /**
  95. * @SecureParam(name="comment", permissions="EDIT, DELETE")
  96. * @SecureParam(name="post", permissions="OWNER")
  97. */
  98. public function secureMethod($comment, $post)
  99. {
  100. // ...
  101. }
  102. }
  103. @SecureReturn
  104. ~~~~~~~~~~~~~
  105. This annotation lets you define restrictions for the value which is returned by
  106. the method. This is also only useful if the returned value is a domain object::
  107. <?php
  108. use JMS\SecurityExtraBundle\Annotation\SecureReturn;
  109. class MyService
  110. {
  111. /**
  112. * @SecureReturn(permissions="VIEW")
  113. */
  114. public function secureMethod()
  115. {
  116. // ...
  117. return $domainObject;
  118. }
  119. }
  120. @RunAs
  121. ~~~~~~
  122. This annotation lets you specifiy roles which are added only for the duration
  123. of the method invocation. These roles will not be taken into consideration
  124. for before, or after invocation access decisions.
  125. This is typically used to implement a two-tier service layer where you have
  126. public and private services, and private services are only to be invoked
  127. through a specific public service::
  128. <?php
  129. use JMS\SecurityExtraBundle\Annotation\Secure;
  130. use JMS\SecurityExtraBundle\Annotation\RunAs;
  131. class MyPrivateService
  132. {
  133. /**
  134. * @Secure(roles="ROLE_PRIVATE_SERVICE")
  135. */
  136. public function aMethodOnlyToBeInvokedThroughASpecificChannel()
  137. {
  138. // ...
  139. }
  140. }
  141. class MyPublicService
  142. {
  143. protected $myPrivateService;
  144. /**
  145. * @Secure(roles="ROLE_USER")
  146. * @RunAs(roles="ROLE_PRIVATE_SERVICE")
  147. */
  148. public function canBeInvokedFromOtherServices()
  149. {
  150. return $this->myPrivateService->aMethodOnlyToBeInvokedThroughASpecificChannel();
  151. }
  152. }
  153. @SatisfiesParentSecurityPolicy
  154. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  155. This must be defined on a method that overrides a method which has security metadata.
  156. It is there to ensure that you are aware the security of the overridden method cannot
  157. be enforced anymore, and that you must copy over all annotations if you want to keep
  158. them.