You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Security LDAP空密码校验问题技术咨询

实现Spring Security LDAP空密码检查功能

你目前是用ActiveDirectoryLdapAuthenticationProvider配置AD LDAP认证,要实现空密码检查,有两种实用的方案可以选:

方案一:前置过滤器提前拦截

在请求进入LDAP认证流程前,通过自定义过滤器先检查密码是否为空,直接阻断无效请求:

import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class EmptyPasswordCheckFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    protected String obtainPassword(HttpServletRequest request) {
        String password = super.obtainPassword(request);
        if (password == null || password.trim().isEmpty()) {
            throw new AuthenticationServiceException("密码不能为空");
        }
        return password;
    }
}

接着在Spring Security配置类里替换默认的过滤器:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .addFilterBefore(new EmptyPasswordCheckFilter(), UsernamePasswordAuthenticationFilter.class)
        // 保留你原有的其他配置
        .authenticationProvider(activeDirectoryLdapAuthenticationProvider());
}

方案二:包装LDAP Provider在认证环节检查

如果想在认证提供者层面处理,可以包装现有的ActiveDirectoryLdapAuthenticationProvider,在调用实际认证逻辑前先做空密码校验:

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;

public class EmptyPasswordCheckingLdapProvider implements AuthenticationProvider {

    private final AuthenticationProvider delegateProvider;

    public EmptyPasswordCheckingLdapProvider(AuthenticationProvider delegateProvider) {
        this.delegateProvider = delegateProvider;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        String password = (String) authentication.getCredentials();
        if (password == null || password.trim().isEmpty()) {
            throw new BadCredentialsException("密码不能为空");
        }
        return delegateProvider.authenticate(authentication);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return delegateProvider.supports(authentication);
    }
}

然后修改你原有的configure(AuthenticationManagerBuilder auth)方法:

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    String domain = customProperties.getAdDomain();
    String url = customProperties.getAdUrl();
    ActiveDirectoryLdapAuthenticationProvider ldapProvider = new ActiveDirectoryLdapAuthenticationProvider(domain,url);
    ldapProvider.setConvertSubErrorCodesToExceptions(true);
    ldapProvider.setUseAuthenticationRequestCredentials(true);
    ldapProvider.setUserDetailsContextMapper(userDetailsContextMapper); // 补全你原本的UserDetailsContextMapper配置

    // 用自定义Provider包装原有LDAP Provider,添加空密码检查
    auth.authenticationProvider(new EmptyPasswordCheckingLdapProvider(ldapProvider));
}

小提示

  • 过滤器方案拦截时机更早,能减少后续不必要的流程开销;Provider方案更贴合Spring Security的认证链逻辑,适合需要和其他认证环节联动的场景。
  • 抛出的异常可以根据业务需求调整,比如用自定义异常类,方便后续统一处理异常提示信息。

内容的提问来源于stack exchange,提问作者Алексей Мокрев

火山引擎 最新活动