Spring Security自定义ldapAuthenticationProvider +自定义ldapAuthoritiesPopulator

时间:2017-08-06 14:36:52

标签: spring-security spring-security-ldap

是否可以拥有自定义ldap身份验证提供程序以及自定义ldap权限populator?

每次ldap服务器无法在短时间内无法访问时我都不想重启我的应用程序(所以我需要自定义提供程序,创建新的上下文并在每次登录时覆盖authenticate方法)。

另一方面,我需要为ldap用户的每个成员创建自定义角色(需要覆盖getGrantedAuthorities)

1 个答案:

答案 0 :(得分:0)

要实现自定义ldap身份验证提供程序,您需要创建从AbstractLdapAuthenticator

扩展的类
public class BindPasswordAuthentificator extends AbstractLdapAuthenticator {

    public BindPasswordAuthentificator(BaseLdapPathContextSource contextSource) {
        super(contextSource);
    }

    @Override
    public DirContextOperations authenticate(Authentication authentication) {
        DirContextOperations user;

        String username = authentication.getName();
        String password = (String)authentication.getCredentials();

        user = authenticateByLdap(username, password); // authenticate user here

        if (user == null) {
            throw new BadCredentialsException(
                    messages.getMessage("BindAuthenticator.badCredentials", "Bad credentials"));
        }

        return user;
    }
}

要实现ldap权限populator,您需要创建从LdapAuthoritiesPopulator

扩展的类
public class CustomLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {

    @Override
    public Collection<? extends GrantedAuthority> getGrantedAuthorities(DirContextOperations userData, String username) {
        Collection<GrantedAuthority> gauth = new HashSet<>();
        //you need to place logic for populating user authorities here
        return gauth;
    }
}

之后,您需要在配置中配置这两个类

@Configuration
@PropertySource("classpath:application.properties")
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${life.ldap.server}")
    private String ldapServer;

    @Autowired
    public void globalUserDetails(final AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(ldapAuthenticationProvider());
    }

    @Bean
    public LdapAuthenticationProvider ldapAuthenticationProvider() {
        return new LdapAuthenticationProvider(authentificator(), authPopulator());
    }

    @Bean
    public BindPasswordAuthentificator authentificator() {
        return new BindPasswordAuthentificator(contextSource());
    }

    @Bean
    public DefaultSpringSecurityContextSource contextSource() {
        return new DefaultSpringSecurityContextSource(ldapServer);
    }

    @Bean
    public CustomLdapAuthoritiesPopulator authPopulator() {
        CustomLdapAuthoritiesPopulator result = new CustomLdapAuthoritiesPopulator();
        return result;
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/login").permitAll()
                .antMatchers("/oauth/token/revokeById/**").permitAll()
                .antMatchers("/tokens/**").permitAll()
                .anyRequest().authenticated()
                .and().formLogin().permitAll()
                .and().csrf().disable();
    }
}