22.1 Overview(概要)

采用“默认拒绝”通常被认为是良好的安全实践,在这种情况下,您明确指定什么是允许的,什么是不允许的。定义未经身份验证的用户可以访问的内容也是类似的情况,尤其是对于web应用程序。许多网站要求用户必须通过除了几个网址之外的任何东西的认证(例如主页和登录页面)。在这种情况下,为这些特定的网址定义访问配置属性是最简单的,而不是为每个受保护的资源定义。换句话说,有时候说ROLE_SOMETHING 是默认需要的,并且只允许这个规则的某些例外,比如应用程序的登录、注销和主页。您也可以从筛选器链中完全省略这些页面,从而绕过访问控制检查,但这可能是不可取的,因为其他原因,特别是如果页面对经过身份验证的用户表现不同。

这就是我们所说的匿名认证。请注意,“匿名认证”用户和未经认证的用户之间没有真正的概念上的区别。Spring Security的匿名身份验证只是为您提供了一种更方便的方式来配置您的访问控制属性。例如,对诸如getCallerPrincipal之类的servlet应用编程接口调用仍将返回空值,即使在SecurityContextHolder中实际上有一个匿名身份验证对象。

在其他情况下,匿名身份验证是有用的,例如当审核拦截器查询SecurityContextHolder以确定哪个主体负责给定的操作时。如果类知道SecurityContextHolder总是包含一个身份验证对象,并且从不为空,那么它们可以被更健壮地创作。

 22.2 Configuration(配置)

匿名身份验证支持在使用超文本传输协议配置Spring Security 3.0时自动提供,并且可以使用<anonymous>元素进行自定义(或禁用)。除非使用传统的bean配置,否则不需要配置这里描述的bean。

三个类一起提供匿名身份验证功能。匿名用户身份验证令牌(AnonymousAuthenticationToken )是身份验证(Authentication)的一种实现,它存储应用于匿名主体的授权。有一个相应的匿名用户身份验证提供程序(AnonymousAuthenticationProvider),它被链接到提供程序管理器(ProviderManager )中,以便接受匿名用户身份验证令牌(AnonymousAuthenticationToken )。最后,还有一个AnonymousAuthenticationFilter,它链接在正常的身份验证机制之后,如果没有现有的身份验证,它会自动将AnonymousAuthenticationToken添加到SecurityContextHolder中。筛选器和身份验证提供程序的定义如下所示:

22. Anonymous Authentication(匿名认证)-风君雪科技博客
 

该密钥在过滤器和认证提供者之间共享,因此前者创建的令牌被后者接受[18]。用户属性以用户名的形式表示在usernameInTheAuthenticationToken,grantedAuthority[,grantedAuthority]。这与在InMemoryDaoImpl的userMap属性的等号后面使用的语法相同。

如前所述,匿名身份验证的好处是所有URI模式都可以应用安全性。例如:

22. Anonymous Authentication(匿名认证)-风君雪科技博客

22.3 AuthenticationTrustResolver(身份验证信任解决方案)

 

匿名身份验证讨论的另一个方面是身份验证身份验证解析器接口(AuthenticationTrustResolver )及其相应的身份验证身份验证身份验证解析器(AuthenticationTrustResolverImpl)实现。这个接口提供了一个身份验证方法(isAnonymous(Authentication)),它允许感兴趣的类考虑这种特殊类型的身份验证状态。异常转换筛选器(ExceptionTranslationFilter )在处理访问拒绝异常(AccessDeniedException )时使用此接口。如果引发了一个AccessDeniedException,并且身份验证是匿名类型的,则过滤器将改为启动AuthenticationEntryPoint,以便主体可以正确地进行身份验证,而不是引发403(禁止的)响应。这是一个必要的区别,否则主体将总是被认为是“已认证的”,并且永远没有机会通过表单、基本、摘要或一些其他正常的认证机制登录。

您经常会看到上面拦截器配置中的ROLE_ANONYMOUS属性被替换为IS _ AUTHORITY _ ANONYMOUS,这在定义访问控制时实际上是一回事。这是使用授权投票者(AuthenticatedVoter )的一个例子,我们将在授权一章中看到。它使用身份验证信任解析器(AuthenticationTrustResolver )来处理这个特定的配置属性,并向匿名用户授予访问权限。认证投票者(AuthenticatedVoter )方法更强大,因为它允许您区分匿名、记住我和完全认证的用户。如果您不需要这个功能,那么您可以继续使用角色匿名(ROLE_ANONYMOUS),它将由Spring Security的标准角色投票器处理。

密钥属性的使用不应被视为提供任何真正的安全性。这只是一个记账练习。如果您共享一个包含匿名用户身份验证提供程序的提供程序管理器,在这种情况下,身份验证客户端可能会构建身份验证对象(例如通过RMI调用),那么恶意客户端可能会提交它自己创建的匿名用户身份验证令牌(带有选定的用户名和授权列表)。如果密钥是可猜测的或者可以被发现,那么令牌将被匿名提供者接受。这对于正常使用来说不是问题,但是如果您正在使用RMI,您最好使用一个定制的提供者管理器,它省略了匿名提供者,而不是共享您用于您的超文本传输协议认证机制的提供者。