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) authentication.getCredentials(); if (!StringUtils.hasLength(username)) { throw new BadCredentialsException("Empty Username"); } if (!StringUtils.hasLength(password)) { throw new BadCredentialsException("Empty Password"); } List<User> users = userRepository.findByUsername(username); if (CollectionUtils.isEmpty(users)) { throw new BadCredentialsException("Bad credentials"); } UserDetails user = users.get(0); if (authenticateByLdap) { doLdapAuthentication(userToken); } else { if (passwordCompar) { String encodePassword = pwEncoder.encodePassword(password, null); if (!encodePassword.equals(user.getPassword())) { throw new BadCredentialsException("Bad credentials"); } } } return createSuccessfulAuthentication(userToken, user); } protected DirContextOperations doLdapAuthentication(UsernamePasswordAuthenticationToken authentication) { try { return authenticator.authenticate(authentication); } catch (Exception e) { logger.error(e.getMessage(), e); throw new BadCredentialsException("Bad credentials"); } } @Override public boolean supports(Class<?> authentication) { return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication); } protected Authentication createSuccessfulAuthentication(UsernamePasswordAuthenticationToken authentication, UserDetails user) { Object password = authentication.getCredentials(); UsernamePasswordAuthenticationToken result = new UsernamePasswordAuthenticationToken(user, password, user.getAuthorities()); result.setDetails(authentication.getDetails()); return result; } // set method... }