我有一个自定义身份验证CustomAuthenticationProvider类,它通过命中LDAP远程服务器来验证用户。我设法创建并配置自定义身份验证提供程序,但无法调用SecurityConfiguration中定义的doAuthentication方法。
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
private final Logger log=LoggerFactory.getLogger(CustomAuthenticationProvider.class);
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = (String) authentication.getCredentials();
if (username == null) {
throw new BadCredentialsException("User is not found");
}
if (password == null) {
throw new BadCredentialsException("Password is not found");
}
try {
LdapContextSource ldapContextSource = new LdapContextSource();
ldapContextSource.setUrl("ldap://jnj.com:3268");
ldapContextSource.setBase("dc=jnj,dc=com");
ldapContextSource.setUserDn(username);
ldapContextSource.setPassword(password);
try {
// initialize the context
ldapContextSource.afterPropertiesSet();
} catch (Exception e) {
e.printStackTrace();
}
LdapTemplate ldapTemplate = new LdapTemplate(ldapContextSource);
ldapTemplate.afterPropertiesSet();
// ldapTemplate.setIgnorePartialResultException(true); // Active Directory doesn’t transparently handle referrals. This fixes that.
AndFilter filter = new AndFilter();
filter.and(new EqualsFilter("sAMAccountName", username));
try {
boolean authed = ldapTemplate.authenticate("", filter.toString(), password);
log.debug("Auuthenticated : "+authed);
} catch (org.springframework.ldap.AuthenticationException ee) {
//userDisplay.setText(“Invalid Username/Password”);
}
} catch (Exception e) {
e.printStackTrace();
}
Collection<? extends GrantedAuthority> authorities = Collections.singleton(new SimpleGrantedAuthority("ROLE_USER"));
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password, authorities);
return authenticationToken;
// return new UsernamePasswordAuthenticationToken(username,password);
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
在SecurityConfiguration中调用此方法,我需要将此方法绑定到我的CustomAuthenticationProvider类
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth) {
try {
auth.authenticationProvider(authProvider)
.ldapAuthentication().userDetailsContextMapper(userDetailsContextMapper())
.ldapAuthoritiesPopulator(ldapAuthoritiesPopulator()).userSearchBase(USER_SEARCH_BASE)
.userSearchFilter(USER_SEARCH_FILTER).groupSearchBase(GROUP_SEARCH_BASE)
.groupSearchFilter(GROUP_SEARCH_FILTER).contextSource(contextSource());
} catch (Exception e) {
throw new BeanInitializationException("Security configuration failed", e);
}
}
我需要调用LDAP
的方法 protected DirContextOperations doAuthentication(UsernamePasswordAuthenticationToken auth) {
String username = auth.getName();
String password = (String) auth.getCredentials();
DirContext ctx = bindAsUser(username, password);
try {
return searchForUser(ctx, username);
} catch (NamingException e) {
log.error("Failed to locate directory entry for authenticated user: " + username, e);
throw badCredentials(e);
} finally {
LdapUtils.closeContext(ctx);
}
}