日期:2014-05-16  浏览次数:20892 次

Spring Security , authenticate use LDAP& DataBase.
基础部分参见:
http://suene.iteye.com/blog/1829807


	<authentication-manager>
		<authentication-provider ref="authenticationProvider" />
	</authentication-manager>

	<beans:bean id="authenticationProvider" class="org.e.simple.authtication.LdapAndDbAuthenticationProvider">
		<beans:property name="authenticateByLdap" value="false" />
		<beans:property name="url" value="ldap://localhost:10389/dc=example,dc=com" /> 
		<beans:property name="userSearchBase" value="ou=Users" />
		<beans:property name="hash" value="{sha}" />
	</beans:bean>


/** 先根据属性 {@link #authenticateByLdap }, 是否使用 LDAP 验证 用户信息. 否则使用数据库查询验证用户.<br/>
 * 
 * 如果验证成功,则以数据库获取用户的权限. */
public class LdapAndDbAuthenticationProvider implements AuthenticationProvider
{

	private static final Logger logger = LoggerFactory.getLogger(LdapAndDbAuthenticationProvider.class);

	@Autowired
	private UserRepository userRepository;

	/** LDAP server */
	private DefaultSpringSecurityContextSource contextSource;

	/** LdapAuthenticator */
	private LdapAuthenticator authenticator;

	/** 是否使用 LDAP 验证用户. */
	private boolean authenticateByLdap;

	// ldap url
	private String url;

	// <user-dn-pattern/>
	private String userDnPattern;

	// <user-search-filter/>
	private String userSearchFilter = "(uid={0})";

	// <user-search-base/>
	private String userSearchBase = "";

	// <password-compare />
	// 是否验证密码.
	private boolean passwordCompar = true;

	// <password-attribute/>
	private String passwordAttribute = "userPassword";

	// password-compare : hash
	// default = plaintext
	// 参考 org.springframework.security.config.authentication.PasswordEncoderParser.ENCODER_CLASSES
	private String hash = "plaintext";

	// password-encoder : base64
	private boolean useBase64;

	// 获取对应的 pwEncoder
	private PasswordEncoder pwEncoder;

	@PostConstruct
	public void init() throws Exception
	{

		if (passwordCompar)
		{

			AbstractBeanDefinition def = (AbstractBeanDefinition) PasswordEncoderParser.createPasswordEncoderBeanDefinition(hash, useBase64);
			Object pwEncoderObj = def.getBeanClass().newInstance();

			if (pwEncoderObj instanceof BaseDigestPasswordEncoder)
			{
				((BaseDigestPasswordEncoder) pwEncoderObj).setEncodeHashAsBase64(useBase64);
			}

			if (pwEncoderObj instanceof PasswordEncoder)
			{
				this.pwEncoder = (PasswordEncoder) pwEncoderObj;
			}
		}

		if (authenticateByLdap)
		{
			contextSource = new DefaultSpringSecurityContextSource(url);
			contextSource.afterPropertiesSet();

			LdapUserSearch userSearch = new FilterBasedLdapUserSearch(this.userSearchBase, this.userSearchFilter, contextSource);

			String[] userDnPatternArray = new String[0];

			if (StringUtils.hasText(userDnPattern))
			{
				userDnPatternArray = new String[]
				{ userDnPattern };
			}

			if (passwordCompar)
			{
				authenticator = new PasswordComparisonAuthenticator(contextSource);
				((PasswordComparisonAuthenticator) authenticator).setPasswordAttributeName(passwordAttribute);
				((PasswordComparisonAuthenticator) authenticator).setPasswordEncoder((PasswordEncoder) pwEncoder);
				((PasswordComparisonAuthenticator) authenticator).setUserDnPatterns(userDnPatternArray);
				((PasswordComparisonAuthenticator) authenticator).setUserSearch(userSearch);

			} else
			{
				authenticator = new BindAuthenticator(contextSource);
				((BindAuthenticator) authenticator).setUserDnPatterns(userDnPatternArray);
				((BindAuthenticator) authenticator).setUserSearch(userSearch);
			}
		}
	}

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException
	{
		final UsernamePasswordAuthenticationToken userToken = (UsernamePasswordAuthenticationToken) authentication;

		String username = userToken.getName();
		String password = (String) authen