SpringSecurity笔记3-Authenticating Users:Authenticaton Strategy
????? 每个应用程序在存储用户信息时采取的策略是不同的,可以是数据库,LDAP目录,CAS认证等,SpringSecurity支
持的认证策略有:
????? (1)In-memory (Spring-configured) user repositories.
????? (2)JDBC-based user repositories.
????? (3)LDAP-based user repositories.
????? (4)OpenID decentralized user identity systems.
????? (5)Central Authentication System (CAS)
????? (6)X.509 certificates
????? (7)JAAS-based providers
????? 当然也支持用户自定义。
????? 下面的讲解以该配置为基础:
????? <http auto-config="true">
??????????? <intercept-url pattern="/**" access="ROLE_SPITTER" />
????? </http>
1. 配置基于内存的用户信息Repository
??? 即在Spring配置文件中配置,使用<user-service>元素:
??? <user-service id="userService">
?????????? <user name="habuma" password="letmein" authorities="ROLE_SPITTER,ROLE_ADMIN"/>
?????????? <user name="twoqubed" password="longhorns" authorities="ROLE_SPITTER"/>
?????????? <user name="admin" password="admin" authorities="ROLE_ADMIN"/>
??? </user-service>
??? 使用<authentication-manager>元素注册认证管理器:
??? <authentication-manager alias="authenticationManager">
???????????? <authentication-provider user-service-ref="userService" />
??? </authentication-manager>
??? 通过这种方式是注册了一个ProviderManager,认证管理将认证工作委托给一个或多个认证Provider, 此时认证
??? Provider需要user service 提供User 信息。
??? 与上面配置等价的内嵌式配置(不推荐):
??? <authentication-provider>
???????????? <user-service id="userService">
??????????????????? <user name="habuma" password="letmein" authorities="ROLE_SPITTER,ROLE
????????????????????????????? _ADMIN"/>
???????????? ...
???????????? </user-service>
??? </authentication-provider>
2. 配置基于数据库的用户信息Repository
??? 即使用:<jdbc-user-service>元素,使用原理与user-service相同:
??? <jdbc-user-service id="userService" data-source-ref="dataSource" />
??? 该配置使用data-source-ref属性指定数据源,通过该配置user service查找用户信息的SQL为:
??? select username,passwd,enabled from users where username = ?
??? 查找用户已经授权的用户SQL:
??? select username,authority from authorities where username = ?
??? 上面着两条SQL语句需要确保用户信息和授权正好存储在指定的表users和authorities中,而jdbc-user-
??? service提供了其他的属性用户客制化查找:
??? (1) users-by-username-query:根据条件用户名查找用户的:username,passwd和enabled状态;
??? (2) authorities-by-username-query: 根据条件用户名查找用户被授予的权限;
??? (3) group-authorities-by-username-query:根据用户名查找用户被授予的组权限。
??? 示例:
??? <jdbc-user-service id="userService" data-source-ref="dataSource"
??????????? users-by-username-query=
????????????????? "select username, password, true from spitter where username=?"
??????????? authorities-by-username-query=
????????????????? "select username,'ROLE_SPITTER' from spitter where username=?" />
3. 配置基于的用户信息Repository
??? 该配置适合于具有层级目录结构的授权体系。需要首先添加依赖:
??? <dependency>
?????????? <groupId>org.springframework.security</groupId>
?????????? <artifactId>spring-security-ldap</artifactId>
?????????? <version>3.0.7.RELEASE</version>
??? </dependency>
??? 有两种配置方式:
??? (1) With an LDAP-oriented authentication provider
? ? (2) With an LDAP-oriented user service
??? (1) 声明一个LDAP Authentication Provider
??? <authentication-manager alias="authenticationManager">
??????????? <ldap-authentication-provider user-search-filter="(uid={0})"
???????????? group-search-filter="member={0}"/>
??? </authentication-manager>
??? 该配置中user-search-filter 和 group-search-filter属性用于提供一个过滤器,用与在基于LDAP查询用户和
??? 组信息时,默认情况下该查找是从LDAP的Root开始查找,下面的配置可以指定query base:
??? <ldap-user-service id="userService"
??????????? user-search-base="ou=people"
??????????? user-search-filter="(uid={0})"
??????????? group-search-base="ou=groups"
??????????? group-search-filter="member={0}" />
??? 该配置中指定查找用户的组织从"people"开始,查找组织从"groups"开始。
??? (2) 配置一个Passwdor Comparison
??? 默认的进行LDAP认证策略是执行一个bind操作,直接与LDAP Server交互认证;另一种做法是执行一个
??? Comparison操作,这种方式是将密码发送至LDAP服务器,要求服务器进行密码比对,需要保证密码安全:
??? <ldap-authentication-provider
??????????? user-search-filter="(uid={0})"
??????????? group-search-filter="member={0}">
??????????? <password-compare />
??? </ldap-authentication-provider>
??? 该配置默认需要登录表单中有userPassword属性,如果Password定义在不同的属性中,可配置成:
??? <password-compare hash="md5" password-attribute="passcode" />
??? 配置中hash="md5"指定了密码的加密策略,默认支持的策略有:
??? {sha},{ssha},md4,md5,plaintext,sha,sha-256
??? (3) 声明一个LDAP User Service
??? <ldap-user-service id="userService"
??????????? user-search-base="ou=people"
??????????? user-search-filter="(uid={0})"
??????????? group-search-base="ou=groups"
??????????? group-search-filter="member={0}" />
??? (4)配置一个内嵌的LDAP Server
??? 默认情况下,SpringSecurity LDAP 认证家丁LDAP Server监听的端口为33389 on localhost, 如果要自定义
??? 在其他的机器上,需使用<ldap-server>元素:
??? <ldap-server url="ldap://habuma.com:389/dc=habuma,dc=com" />
??? 内嵌的配置:
??? <ldap-server root="dc=habuma,dc=com" />
??? 其中root是可选的,默认是"dc=springframework,dc=org",当然也可自己定义。
??? <ldap-server root="dc=habuma,dc=com" ldif="classpath:users.ldif" />
??? 在上述这个配置中,将从classpath中查找所有LDIF文件,若要明确指定需使用ldif属性。
??? 示例LDIF file:
??? dn: ou=groups,dc=habuma,dc=com
??? objectclass: top
??? objectclass: organizationalUnit
??? ou: groups
??? dn: ou=people,dc=habuma,dc=com
??? objectclass: top
??? objectclass: organizationalUnit
??? ou: people
??? dn: uid=habuma,ou=people,dc=habuma,dc=com
??? objectclass: top
??? objectclass: person
??? objectclass: organizationalPerson
??? objectclass: inetOrgPerson
??? cn: Craig Walls
??? sn: Walls
??? uid: habuma
??? userPassword: password
???
??? dn: uid=jsmith,ou=people,dc=habuma,dc=com
??? objectclass: top
??? objectclass: person
??? objectclass: organizationalPerson
??? objectclass: inetOrgPerson
??? cn: John Smith
??? sn: Smith
??? uid: jsmith
??? userPassword: password
???
??? dn: cn=spitter,ou=groups,dc=habuma,dc=com
??? objectclass: top
??? objectclass: groupOfNames
??? cn: spitter
??? member: uid=habuma,ou=people,dc=habuma,dc=com
4. 启用Remember-ME功能
??? 需在<http>元素中使用<remember-me>元素:
??? <http auto-config="true" use-expressions="true">
??????????? ...
??????????? <remember-me key="spitterKey" token-validity-seconds="2419200" />
??? </http>
??? 如果不指定token-validity-seconds="2419200",默认情况下在cookie中存储有效信息2周,指定该信息后将
??? 有效期改为4周。存储在Cookie中的数据包括username,password, expiration date,private key,这些数据
??? 在存储前均已经被MD5编码,默认的可以是:SpringSecured",此出自定义为"spitterKey". 使用该功能需要在
??? Form 中增加属性:_spring_security_remember_me:
??? <input id="remember_me" name="_spring_security_remember_me" type="checkbox"/>
??? <label for="remember_me" class="inline">Remember me</label>.