Spring Security身份验证详细介绍( 九 )

Authentication
Spring Security的LDAP支持不使用UserDetailsService,因为LDAP绑定身份验证不允许客户端读取密码,甚至是密码的哈希版本 。这意味着Spring Security无法读取密码并对其进行身份验证 。
因此,LDAP支持是使用LdapAuthenticator接口实现的 。LdapAuthenticator还负责检索任何必需的用户属性 。这是因为属性上的权限可能取决于所使用的身份验证类型 。例如,如果绑定为用户,可能需要使用用户自己的权限读取它们 。
Spring Security提供了两个LdapAuthenticator实现:

  • 使用绑定验证
  • 使用密码身份验证
使用绑定验证
绑定身份验证是使用LDAP对用户进行身份验证的最常用机制 。在绑定身份验证中,用户凭证(即用户名/密码)被提交给LDAP服务器,由LDAP服务器对用户进行身份验证 。使用绑定身份验证的好处是,用户的秘密信息(即密码)不需要暴露给客户端,这有助于防止它们泄露 。
下面是绑定身份验证配置的示例 。
@BeanBindAuthenticator authenticator(BaseLdapPathContextSource contextSource) {BindAuthenticator authenticator = new BindAuthenticator(contextSource);authenticator.setUserDnPatterns(new String[] { "uid={0},ou=people" });return authenticator;}@BeanLdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {return new LdapAuthenticationProvider(authenticator);}这个简单的示例通过在提供的模式中替换用户登录名并尝试将登录密码绑定为该用户来获得用户DN 。如果您的所有用户都存储在目录中的单个节点下,那么这是可以的 。如果你想要配置一个LDAP搜索过滤器来定位用户,你可以使用以下方法:
@BeanBindAuthenticator authenticator(BaseLdapPathContextSource contextSource) {String searchBase = "ou=people";String filter = "(uid={0})";FilterBasedLdapUserSearch search =new FilterBasedLdapUserSearch(searchBase, filter, contextSource);BindAuthenticator authenticator = new BindAuthenticator(contextSource);authenticator.setUserSearch(search);return authenticator;}@BeanLdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {return new LdapAuthenticationProvider(authenticator);}如果与上面的ContextSource定义一起使用,这将使用(uid={0})作为过滤器在DN ou=people,dc=springframework,dc=org下执行搜索 。同样,用户登录名被替换为筛选器名称中的参数,因此它将搜索uid属性等于用户名的条目 。如果没有提供用户搜索库,则从根目录执行搜索 。
使用密码身份验证
密码比较是将用户提供的密码与存储在存储库中的密码进行比较 。这可以通过检索密码属性的值并在本地进行检查来完成,也可以通过执行LDAP“比较”操作来完成,在该操作中,将提供的密码传递给服务器进行比较,而永远不会检索真正的密码值 。如果密码用随机的盐值正确哈希,则无法进行LDAP比较 。
示例:最小密码比较配置
@BeanPasswordComparisonAuthenticator authenticator(BaseLdapPathContextSource contextSource) {return new PasswordComparisonAuthenticator(contextSource);}@BeanLdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {return new LdapAuthenticationProvider(authenticator);}下面是一个更高级的配置,包含一些自定义 。
示例:密码比较配置
@BeanPasswordComparisonAuthenticator authenticator(BaseLdapPathContextSource contextSource) {PasswordComparisonAuthenticator authenticator =new PasswordComparisonAuthenticator(contextSource);authenticator.setPasswordAttributeName("pwd");authenticator.setPasswordEncoder(new BCryptPasswordEncoder());return authenticator;}@BeanLdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator) {return new LdapAuthenticationProvider(authenticator);}①指定密码属性为pwd
②使用BCryptPasswordEncoder
LdapAuthoritiesPopulator
Spring Security的ldapauthortiespopulator用于确定为用户返回什么权限 。
示例:LdapAuthoritiesPopulator配置
@BeanLdapAuthoritiesPopulator authorities(BaseLdapPathContextSource contextSource) {String groupSearchBase = "";DefaultLdapAuthoritiesPopulator authorities =new DefaultLdapAuthoritiesPopulator(contextSource, groupSearchBase);authorities.setGroupSearchFilter("member={0}");return authorities;}@BeanLdapAuthenticationProvider authenticationProvider(LdapAuthenticator authenticator, LdapAuthoritiesPopulator authorities) {return new LdapAuthenticationProvider(authenticator, authorities);}Active Directory
Active Directory支持它自己的非标准身份验证选项,并且正常的使用模式不太适合标准
LdapAuthenticationProvider 。通常使用域用户名(格式为user@domain)执行身份验证,而不是使用LDAP专有名称 。为了简化这一点,Spring Security提供了一个为典型的Active Directory设置定制的身份验证提供程序 。


推荐阅读