`
duanjiangong
  • 浏览: 62844 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring Security LDAP认证

阅读更多

10.1. 综述

LDAP通常被公司用作用户信息的中心资源库,同时也被当作一种认证服务。 它也可以为应用用户储存角色信息。

这里有很多如何对LDAP服务器进行配置的场景,所以Spring Security的LDAP提供器也是完全可配置的。 它使用为验证和角色检测提供了单独的策略接口,并提供了默认的实现,这些都是可配置成处理绝大多数情况。

你还是应该熟悉一下LDAP,在你在Spring Security使用它之前。 下面的链接提供了很好的概念介绍,也是一个使用免费的LDAP服务器建立一个目录http://www.zytrax.com/books/ldap/ 的指南。 我们也应该熟悉一下通过JNDI API使用java访问LDAP。 我们没有在LDAP提供器里使用任何第三方LDAP库(Mozilla, JLDAP等等),但是还是用到了Spring LDAP,所以如果你希望自己进行自定义,对这个工程熟悉一下也是有好处的。

10.2. 在Spring Security里使用LDAP

Spring Security的LDAP认证可以粗略分成以下几部分。

  1. 从登录名中获得唯一的“辨别名称 ”或DN。 这就意味着要对目录执行搜索,除非预先知道了用户名和DN之前的明确映射关系。

  2. 验证这个用户,进行绑定用户,或调用远程“比较 ”操作,比对用户的密码和DN在目录入口中的密码属性。

  3. 为这个用户读取权限队列。

例外情况是,当LDAP目录只是用来检索用户信息和进行本地验证的时候,这也许不可能的,因为目录的属性,比如对用户密码属性,常常被设置成只读权限。

让我们看看下面的一些配置场景。 要是想得到所有可用的配置选项,请参考安全命名空间结构(使用你的XML编辑器应该就可以看到所有有效信息)。

10.3. 配置LDAP服务器

你需要做的第一件事是配置服务器,它里面应该存放着认证信息。 这可以使用安全命名空间里的<ldap-server> 元素实现。 使用url 属性指向一个外部LDAP服务器:

    <ldap-server url="ldap://springframework.org:389/dc=springframework,dc=org" />
                
            

 

10.3.1. 使用嵌入测试服务器

这个<ldap-server> 元素也可以用来创建一个嵌入服务器,这在测试和演示的时候特别有用。 在这种情况,你不需要使用url 属性:

    <ldap-server root="dc=springframework,dc=org"/>
        
    

这里我们指定目录的根DIT应该是“dc=springframework,dc=org ”,这是默认的。 使用这种方式,命名空间解析器会建立一个嵌入Apache目录服务器,然后检索classpath下的LDIF文件,尝试从它里边把数据加载到服务器里。 你可以通过ldif 属性自定义这些行为,这样可以定义具体要加载哪个LDIF资源:

    <ldap-server ldif="classpath:users.ldif" />
        

这就让启动和运行LDAP变得更轻松了,因为使用一个外部服务器还是不大方便。 它也避免链接到Apache目录服务器的复杂bean配置。 如果使用普通Spring bean配置方法会变的更加混乱。 你必须把必要的Apache目录依赖的jar放到你的程序中。 这些都可以从LDAP示例程序中获得。

10.3.2. 使用绑定认证

这是一个非常常见的LDAP认证场景。

    <ldap-authentication-provider user-dn-pattern="uid={0},ou=people"/>
                     

这个很简单的例子可以根据用户登录名提供的模式为用户获得DN,然后尝试和用户的登录密码进行绑定。 如果所有用户都保存到一个目录的单独节点下就没有问题。 如果你想配置一个LDAP搜索过滤器来定位用户,你可以使用如下配置:

    <ldap-authentication-provider user-search-filter="(uid={0})" user-search-base="ou=people"/>
                    

如果使用了上面的服务器定义,它会在DNou=people,dc=springframework,dc=org 下执行搜索,使用user-search-filter 里的值作为过滤条件。 然后把用户登录名作为过滤名称的一个参数。 如果没有提供user-search-base ,搜索将从根开始。

10.3.3. 读取授权

如果从LDAP目录的组里读取权限信息呢,这是通过下面的属性控制的。

  • group-search-base 。定义目录树部分,哪个组应该执行搜索。

  • group-role-attribute 。这个属性包含了组入口中定义的权限名称。默认是 cn

  • group-search-filter 。这个过滤器用来搜索组的关系。 默认是uniqueMember={0} ,对应于groupOfUniqueMembers LDAP类。 在这情况下,取代参数是用户的辨别名称。 如果你想对登录名搜索,可以使用{1} 这个参数。

因此,如果我们使用下面进行配置

    <ldap-authentication-provider user-dn-pattern="uid={0},ou=people" group-search-base="ou=groups" />
    

并以用户“ben ”的身份通过认证,在读取权限信息的子流程里,要在目录入口ou=groups,dc=springframework,dc=org 下执行搜索,查找包含uniqueMember 属性值为ou=groups,dc=springframework,dc=org 的入口。 默认,权限名都要以ROLE_ 作为前缀。 你可以使用role-prefix 属性修改它。 如果你不想使用任何前缀,可以使用role-prefix="none" 。 要想得到更多读取权限的信息,可以查看DefaultLdapAuthoritiesPopulator 类的Javadoc。

10.4. 实现类

我们上面使用到的命名空间选项很容易使用,也比使用spring bean更准确。 也有可能你需要知道如何配置在你的application context里配置Spring Security LDAP目录。 比如,你可能想自定义一些类的行为。 如果你想使用命名空间配置,你可以跳过这节,直接进入下一段。

最主要的LDAP提供器类是org.springframework.security.providers.ldap.LdapAuthenticationProvider 。 这个bean自己没做什么事情,而是代理了其他两个bean的工作,一个是LdapAuthenticator ,一个是LdapAuthoritiesPopulator ,用来处理用户认证和检索用户的GrantedAuthority 属性集合。

10.4.1. LdapAuthenticator实现

验证者还负责检索所有需要的用户属性。 这是因为对于属性的授权可能依赖于使用的验证类型 比如,如果对某个用户进行绑定,它也许必须通过用户自己的授权才能进行读取。

当前Spring Security提供两种验证策略:

  • 直接去LDAP服务器验证(“绑定”验证)。

  • 比较密码,将用户提供的密码与资源库中保存的进行比较。 这可以通过检索密码属性的值并在本地检测,或者执行LDAP“比较”操作,提供用来比较的密码是从服务器获得的,绝对不会检索真实密码的值。

 

10.4.1.1. 常用功能

在认证一个用户之前(使用任何一个策略),辨别名称(DN)必须从系统提供的登录名中获得。 这可以通过,简单的模式匹配(设置setUserDnPatterns 数组属性)或者设置userSearch 属性。 为了实现DN模式匹配方法,一个标准的java模式格式被用到了,登录名将被参数{0} 替代。 这个模式应该和DN有关系,并绑定到配置好的SpringSecurityContextSource (看看链接到LDAP服务器 那节,获得更多信息)。 比如,如果你使用了LDAP服务的URL是ldap://monkeymachine.co.uk/dc=springframework,dc=org ,并有一个模式uid={0},ou=greatapes ,然后登录名"gorilla"会映射到DNuid=gorilla,ou=greatapes,dc=springframework,dc=org 。 每个配置好的DN模式将尝试进行定位,直到有一个匹配上。 使用搜索获得信息,看看下面的安全对象 那节。 两种方式也可以结合在一起使用 - 模式会先被检测一下,然后如果没有找到匹配的DN,就会使用搜索。

10.4.1.2. BindAuthenticator

这个类 org.springframework.security.providers.ldap.authenticator.BindAuthenticator 实现了绑定认证策略。 它只是尝试对用户进行绑定。

10.4.1.3. PasswordComparisonAuthenticator

这个类 org.springframework.security.providers.ldap.authenticator.PasswordComparisonAuthenticator 实现了密码比较认证策略。

10.4.1.4. 活动目录认证

除了标准LDAP认证以外(绑定到一个DN),活动目录对于用户认证提供了自己的非标准语法。

10.4.2. 链接到LDAP服务器

上面讨论的bean必须连接到服务器。 它们都必须使用SpringSecurityContextSource ,这个是Spring LDAP的一个扩展。 除非你有特定的需求,你通常只需要配置一个DefaultSpringSecurityContextSource bean,这个可以使用你的LDAP服务器的URL进行配置,可选项还有管理员用户的用户名和密码,这将默认用在绑定服务器的时候(而不是匿名绑定)。 参考Spring LDAP的AbstractContextSource 类的Javadoc获得更多信息。

10.4.3. LDAP搜索对象

通常,比简单DN匹配越来越复杂的策略需要在目录里定位一个用户入口。 这可以使用LdapUserSearch 的一个示例,它可以提供认证者实现,比如让他们定位一个用户。 提供的实现是FilterBasedLdapUserSearch

10.4.3.1.  FilterBasedLdapUserSearch

这个bean使用一个LDAP过滤器,来匹配目录里的用户对象。 这个过程在javadoc里进行过解释,在对应的搜索方法,JDK DirContext class 。 就如那里解释的,搜索过滤条件可以通过方法指定。 对于这个类,唯一合法的参数是{0} ,它会代替用户的登录名。

10.4.4. LdapAuthoritiesPopulator

在成功认证用户之后,LdapAuthenticationProvider 会调用配置好的LdapAuthoritiesPopulator bean,尝试读取用户的授权集合。 这个DefaultLdapAuthoritiesPopulator 是一个实现类,它将通过搜索目录读取授权,查找用户成员所在的组(典型的这会是目录中的groupOfNamesgroupOfUniqueNames 入口)。 查看这个类的Javadoc获得它如何工作的更多信息。

10.4.5. Spring Bean配置

典型的配置方法,使用到像我们这在里讨论的这些bean,就像这样:

<bean id="contextSource"
        class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
  <constructor-arg value="ldap://monkeymachine:389/dc=springframework,dc=org"/>
  <property name="userDn" value="cn=manager,dc=springframework,dc=org"/>
  <property name="password" value="password"/>
</bean>

<bean id="ldapAuthProvider"
        class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
  <constructor-arg>
    <bean class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
      <constructor-arg ref="contextSource"/>
      <property name="userDnPatterns">
        <list><value>uid={0},ou=people</value></list>
      </property>
    </bean>
  </constructor-arg>
  <constructor-arg>
    <bean class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
      <constructor-arg ref="contextSource"/>
      <constructor-arg value="ou=groups"/>
      <property name="groupRoleAttribute" value="ou"/>
    </bean>
  </constructor-arg>
</bean>
                

这里建立了一个提供器,访问LDAP服务,URL是 ldap://monkeymachine:389/dc=springframework,dc=org 。 认证会被执行,尝试绑定这个DN uid=<user-login-name>,ou=people,dc=springframework,dc=org 。 在成功认证之后,会通过查找下面的DN ou=groups,dc=springframework,dc=org 使用默认的过滤条件 (member=<user's-DN>) ,将角色分配给用户。 角色名会通过每个匹配的“ou ”属性获得。

要配置用户的搜索对象,使用过滤条件 (uid=<user-login-name>) 替代DN匹配(或附加到它上面),你需要配置下面的bean

<bean id="userSearch"
    class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
  <constructor-arg index="0" value=""/>
  <constructor-arg index="1" value="(uid={0})"/>
  <constructor-arg index="2" ref="contextSource" />
</bean> 
                

并使用它,设置认证者的userSearch 属性。 这个认证者会调用搜索对象,在尝试绑定到用户之前获得正确的用户DN。

10.4.6. LDAP属性和自定义UserDetails

使用LdapAuthenticationProvider 进行认证的结果,和使用普通Spring Security认证一样,都要使用标准UserDetailsService 接口。 它会创建一个UserDetails 对象,并保存到返回的Authentication 对象里。 在使用UserDetailsService 时,常见的需求是可以自定义这个实现,添加额外的属性。 在使用LDAP的时候,这些基本都来自用户入口的属性。 UserDetails 对象的创建结果被提供者的UserDetailsContextMapper 策略控制,它负责在用户对象和LDAP环境数据之间进行映射:

public interface UserDetailsContextMapper {
    UserDetails mapUserFromContext(DirContextOperations ctx, String username, GrantedAuthority[] authority);

    void mapUserToContext(UserDetails user, DirContextAdapter ctx);
}
                

只有第一个方法与认证有关。 如果你提供这个接口的实现,你可以精确控制如何创建UserDetails对象。 第一个参数是Spring LDAP的DirContextOperations 实例,他给你访问加载的LDAP属性的通道。 username 参数是用来认证的名字,最后一个参数是从用户加载的授权列表。]

环境数据加载的方式不同,视乎你采用的认证方法。 使用BindAuthenticatior ,从绑定操作返回的环境会用来读取属性,否则数据会通过标准的环境,从配置好的ContextSource 获得(当测试配置好定位用户,这会从搜索对象中获得数据)。

分享到:
评论

相关推荐

    Spring Security3.2搭建LDAP认证授权

    **四、Spring Security LDAP认证流程** 1. 用户尝试访问受保护的资源。 2. `AuthenticationManager`接收到请求,找到对应的`LdapAuthenticationProvider`。 3. `LdapAuthenticationProvider`与LDAP服务器通信,验证...

    Spring Security ldap 1.3.2

    LDAP认证流程** Spring Security LDAP的认证流程通常包括以下步骤: - 连接LDAP服务器:配置Spring Security以连接到指定的LDAP服务器。 - 用户名查找:根据用户名查询LDAP目录,寻找匹配的用户条目。 - 密码验证:...

    spring-security-ldap-2.0.1

    2. Spring Security LDAP:Spring Security LDAP是Spring Security的一个模块,它允许开发者将应用的安全认证和授权功能与LDAP服务器集成,从而实现基于目录的服务认证。 二、Spring Security LDAP核心概念 1. ...

    浅谈Spring Security LDAP简介

    浅谈Spring Security LDAP简介 本资源主要介绍了Spring Security LDAP的基本概念和配置方法,通过示例代码和详细的解释,帮助读者更好地理解和应用Spring Security LDAP。 一、Spring Security LDAP概述 LDAP...

    Spring security认证授权

    在这个例子中,我们将深入探讨如何使用Spring Security进行认证和授权,并结合数据库操作进行动态配置。 首先,Spring Security的核心概念包括认证(Authentication)和授权(Authorization)。认证是确认用户身份...

    Spring Security LDAP 全选管理框架 中文版

    通过与LDAP的集成,Spring Security能够利用现有的LDAP服务器来处理用户的认证和授权。这种集成方式不仅简化了开发者的任务,还确保了系统的安全性与稳定性。 **2.2 如何集成Spring Security与LDAP** 1. **添加...

    Spring+LDAP实现单点登录

    在Spring+LDAP的SSO系统中,当用户首次登录时,其凭证被提交到中央认证服务器(通常是一个Spring Security配置的控制器),服务器通过与LDAP服务器交互验证用户身份。成功后,生成一个安全的票据(例如JWT或Ticket ...

    SpringSecurity.pdf

    Spring Security提供了丰富的认证机制,支持多种认证方式,包括但不限于表单认证、LDAP认证、CAS认证等。认证成功后,用户的身份会被标记为已认证,然后系统根据用户的权限来进行授权,授权是指决定一个已认证的用户...

    最详细Spring Security学习资料(源码)

    身份验证:Spring Security支持多种身份验证方式,包括基本认证、表单登录、LDAP认证、OAuth等,同时也支持自定义的认证方式。 授权:Spring Security提供了细粒度的授权机制,可以根据角色、权限进行访问控制。...

    spring-security-samples-ldap

    spring security 3 ldap验证方式示例

    spring-ldap1.3.1

    Spring LDAP很好地融入了Spring生态,可以与其他Spring模块(如Spring JDBC、Spring Security)无缝集成。这使得在处理多种数据存储时,代码风格和事务管理保持一致。 6. "lib"文件夹: 压缩包中的"lib"文件夹很...

    SpringSecurity学习总结源代码

    首先,SpringSecurity的核心功能包括用户认证、权限授权、会话管理以及防止常见攻击。其中,用户认证涉及验证用户凭据,如用户名和密码,以确定用户的身份。而权限授权则决定了已认证的用户可以访问哪些资源或执行...

    spring security3 中文版本

    - `LDAP-spring-security-ldap.jar`:支持 LDAP 认证和授权。 - `ACL-spring-security-acl.jar`:提供了基于 ACL 的访问控制功能。 - `CAS-spring-security-cas-client.jar`:支持 CAS 协议的单点登录功能。 - `...

    spring security3.0所需要的最精简的jar包

    如果涉及到LDAP认证或者对象级别的权限控制,那么相应的模块也需要引入。而`spring-security-config`是配置必不可少的部分,通常都会一起使用。 在实际开发中,除了这些jar包,可能还需要根据具体需求引入Spring ...

    spring security 官方文档

    它可以通过自定义`AuthenticationProvider`来扩展,以适应不同的认证源,如数据库、LDAP服务器或社交登录服务。 2. **授权(Authorization)**:框架提供了基于角色的访问控制(RBAC),允许开发人员定义谁可以访问...

    spring-security 官方文档 中文版

    - **LDAP (spring-security-ldap.jar)**:提供了 LDAP 目录服务支持。 - **ACL (spring-security-acl.jar)**:提供了访问控制列表支持。 - **CAS (spring-security-cas-client.jar)**:提供了与 Central ...

    SpringLdapDemo

    学习SpringSecurity时,看到LDAP认证,不了解LDAP根本无从下手。所以转头学习了一下LDAP,搭建了一个DEMO,仅作记录。 LDAP(Lightweight Directory Access Protocol) 轻量级目录访问协议,LDAP目录以树状的层次结构...

    spring_security_3.1

    1. **身份验证**:Spring Security 提供了多种身份验证机制,包括基于内存的、JDBC的、LDAP的和自定义的。在3.1版本中,你可以配置`UserDetailsService`接口来获取用户信息,并使用`AuthenticationProvider`来处理...

    Spring Security 3多用户登录实现一

    Spring Security提供了统一的异常处理机制,如`AccessDeniedException`(访问被拒绝)和`AuthenticationException`(认证失败)。可以通过实现`AccessDeniedHandler`和`AuthenticationEntryPoint`接口来自定义异常...

    初识 Spring Security - v1.1.pdf

    - **适用于Java工程师**:Spring Security主要针对Java开发者,尤其是那些需要了解如何在企业级应用中实施安全认证和授权的工程师。 - **了解前置知识**:为了更好地学习Spring Security,读者需要具备一定的基础...

Global site tag (gtag.js) - Google Analytics