anon-auth-provider.xml 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="anonymous"
  2. xmlns:xlink="http://www.w3.org/1999/xlink">
  3. <info>
  4. <title>Anonymous Authentication</title>
  5. </info>
  6. <section xml:id="anonymous-overview">
  7. <info>
  8. <title>Overview</title>
  9. </info>
  10. <para>It's generally considered good security practice to adopt a
  11. <quote>deny-by-default</quote> where you explicitly specify what is allowed and disallow
  12. everything else. Defining what is accessible to unauthenticated users is a similar
  13. situation, particularly for web applications. Many sites require that users must be
  14. authenticated for anything other than a few URLs (for example the home and login pages).
  15. In this case it is easiest to define access configuration attributes for these specific
  16. URLs rather than have for every secured resource. Put differently, sometimes it is nice
  17. to say <literal>ROLE_SOMETHING</literal> is required by default and only allow certain
  18. exceptions to this rule, such as for login, logout and home pages of an application. You
  19. could also omit these pages from the filter chain entirely, thus bypassing the access
  20. control checks, but this may be undesirable for other reasons, particularly if the pages
  21. behave differently for authenticated users.</para>
  22. <para>This is what we mean by anonymous authentication. Note that there is no real
  23. conceptual difference between a user who is <quote>anonymously authenticated</quote> and
  24. an unauthenticated user. Spring Security's anonymous authentication just gives you a
  25. more convenient way to configure your access-control attributes. Calls to servlet API
  26. calls such as <methodname>getCallerPrincipal</methodname>, for example, will still
  27. return null even though there is actually an anonymous authentication object in the
  28. <classname>SecurityContextHolder</classname>.</para>
  29. <para>There are other situations where anonymous authentication is useful, such as when an
  30. auditing interceptor queries the <classname>SecurityContextHolder</classname> to
  31. identify which principal was responsible for a given operation. Classes can be authored
  32. more robustly if they know the <classname>SecurityContextHolder</classname> always
  33. contains an <interfacename>Authentication</interfacename> object, and never
  34. <literal>null</literal>.</para>
  35. </section>
  36. <section xml:id="anonymous-config">
  37. <info>
  38. <title>Configuration</title>
  39. </info>
  40. <para>Anonymous authentication support is provided automatically when using the HTTP
  41. configuration Spring Security 3.0 and can be customized (or disabled) using the
  42. <literal>&lt;anonymous></literal> element. You don't need to configure the beans
  43. described here unless you are using traditional bean configuration.</para>
  44. <para>Three classes that together provide the anonymous authentication feature.
  45. <literal>AnonymousAuthenticationToken</literal> is an implementation of
  46. <interfacename>Authentication</interfacename>, and stores the
  47. <interfacename>GrantedAuthority</interfacename>s which apply to the anonymous principal.
  48. There is a corresponding <literal>AnonymousAuthenticationProvider</literal>, which is
  49. chained into the <literal>ProviderManager</literal> so that
  50. <literal>AnonymousAuthenticationToken</literal>s are accepted. Finally, there is an
  51. <classname>AnonymousAuthenticationFilter</classname>, which is chained after the normal
  52. authentication mechanisms and automatically adds an
  53. <literal>AnonymousAuthenticationToken</literal> to the
  54. <classname>SecurityContextHolder</classname> if there is no existing
  55. <interfacename>Authentication</interfacename> held there. The definition of the filter
  56. and authentication provider appears as follows:</para>
  57. <para> <programlisting>
  58. <![CDATA[
  59. <bean id="anonymousAuthFilter"
  60. class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
  61. <property name="key" value="foobar"/>
  62. <property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/>
  63. </bean>
  64. <bean id="anonymousAuthenticationProvider"
  65. class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
  66. <property name="key" value="foobar"/>
  67. </bean>]]>
  68. </programlisting> </para>
  69. <para>The <literal>key</literal> is shared between the filter and authentication provider,
  70. so that tokens created by the former are accepted by the latter<footnote>
  71. <para>The use of the <literal>key</literal> property should not be regarded as providing
  72. any real security here. It is merely a book-keeping exercise. If you are sharing a
  73. <classname>ProviderManager</classname> which contains an
  74. <classname>AnonymousAuthenticationProvider</classname> in a scenario where it is
  75. possible for an authenticating client to construct the
  76. <interfacename>Authentication</interfacename> object (such as with RMI invocations),
  77. then a malicious client could submit an
  78. <classname>AnonymousAuthenticationToken</classname> which it had created itself
  79. (with chosen username and authority list). If the <literal>key</literal> is
  80. guessable or can be found out, then the token would be accepted by the anonymous
  81. provider. This isn't a problem with normal usage but if you are using RMI you would
  82. be best to use a customized <classname>ProviderManager</classname> which omits the
  83. anonymous provider rather than sharing the one you use for your HTTP authentication
  84. mechanisms.</para>
  85. </footnote>. The <literal>userAttribute</literal> is expressed in the form of
  86. <literal>usernameInTheAuthenticationToken,grantedAuthority[,grantedAuthority]</literal>.
  87. This is the same syntax as used after the equals sign for
  88. <literal>InMemoryDaoImpl</literal>'s <literal>userMap</literal> property.</para>
  89. <para>As explained earlier, the benefit of anonymous authentication is that all URI patterns
  90. can have security applied to them. For example:</para>
  91. <para> <programlisting>
  92. <![CDATA[
  93. <bean id="filterSecurityInterceptor"
  94. class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
  95. <property name="authenticationManager" ref="authenticationManager"/>
  96. <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>
  97. <property name="securityMetadata">
  98. <security:filter-security-metadata-source>
  99. <security:intercept-url pattern='/index.jsp' access='ROLE_ANONYMOUS,ROLE_USER'/>
  100. <security:intercept-url pattern='/hello.htm' access='ROLE_ANONYMOUS,ROLE_USER'/>
  101. <security:intercept-url pattern='/logoff.jsp' access='ROLE_ANONYMOUS,ROLE_USER'/>
  102. <security:intercept-url pattern='/login.jsp' access='ROLE_ANONYMOUS,ROLE_USER'/>
  103. <security:intercept-url pattern='/**' access='ROLE_USER'/>
  104. </security:filter-security-metadata-source>" +
  105. </property>
  106. </bean>]]>
  107. </programlisting> </para>
  108. </section>
  109. <section xml:id="anonymous-auth-trust-resolver">
  110. <title><interfacename>AuthenticationTrustResolver</interfacename></title>
  111. <para> Rounding out the anonymous authentication discussion is the
  112. <interfacename>AuthenticationTrustResolver</interfacename> interface, with its
  113. corresponding <literal>AuthenticationTrustResolverImpl</literal> implementation. This
  114. interface provides an <literal>isAnonymous(Authentication)</literal> method, which
  115. allows interested classes to take into account this special type of authentication
  116. status. The <classname>ExceptionTranslationFilter</classname> uses this interface in
  117. processing <literal>AccessDeniedException</literal>s. If an
  118. <literal>AccessDeniedException</literal> is thrown, and the authentication is of an
  119. anonymous type, instead of throwing a 403 (forbidden) response, the filter will instead
  120. commence the <interfacename>AuthenticationEntryPoint</interfacename> so the principal
  121. can authenticate properly. This is a necessary distinction, otherwise principals would
  122. always be deemed <quote>authenticated</quote> and never be given an opportunity to login
  123. via form, basic, digest or some other normal authentication mechanism. </para>
  124. <para> You will often see the <literal>ROLE_ANONYMOUS</literal> attribute in the above
  125. interceptor configuration replaced with <literal>IS_AUTHENTICATED_ANONYMOUSLY</literal>,
  126. which is effectively the same thing when defining access controls. This is an example of
  127. the use of the <classname>AuthenticatedVoter</classname> which we will see in the <link
  128. xlink:href="#authz-authenticated-voter">authorization chapter</link>. It uses an
  129. <interfacename>AuthenticationTrustResolver</interfacename> to process this particular
  130. configuration attribute and grant access to anonymous users. The
  131. <classname>AuthenticatedVoter</classname> approach is more powerful, since it allows you
  132. to differentiate between anonymous, remember-me and fully-authenticated users. If you
  133. don't need this functionality though, then you can stick with
  134. <literal>ROLE_ANONYMOUS</literal>, which will be processed by Spring Security's standard
  135. <classname>RoleVoter</classname>. </para>
  136. </section>
  137. </chapter>