基础部分参见:
http://suene.iteye.com/blog/1829807
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...
}