Где реализовать создание пользователей базы данных и назначения ролей для аутентификации LDAP с помощью Spring Boot Security - PullRequest
0 голосов
/ 30 сентября 2019

У меня есть приложение, которое использует 2 формы аутентификации: LDAP и базу данных для внешних пользователей. У меня нет пользователей LDAP, зарегистрированных в базе данных, потому что их более 10 000, и хотя я реализовал обе аутентификации, я не смог реализовать роли для пользователей, которые входят в систему через LDAP, он просто перенаправляет их настраница ошибки whitelabel. Я имею в виду, что, когда кто-то успешно проходит аутентификацию через LDAP, для него создается пользователь в базе данных и ему назначается стандартная роль, но я не знаю, где бы я это реализовал.

Мой класс WebSecurityConfig:

@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/css/**", "/img/**", "/js/**", "/webjars/**").permitAll()
                .antMatchers("/user/updatePassword*").hasAuthority("CHANGE_PASSWORD_PRIVILEGE")
                .antMatchers("/login", "/register/**", "/user/**").permitAll()
                .antMatchers("/createUser").access("hasRole('CLIENT') or hasRole('ADMIN')")
                .anyRequest().hasAuthority("USER")
                .and()
            .formLogin()
                .loginPage("/login")
                .successHandler(successHandler)
                .permitAll()
                .and()
            .logout()
                .invalidateHttpSession(true)
                .deleteCookies("JSESSIONID")
                .and()
            .csrf()
                .disable();

        http.sessionManagement().maximumSessions(3).maxSessionsPreventsLogin(true).sessionRegistry(sessionRegistry());
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth
                .authenticationProvider(customAuthenticationProvider);//DB authentication for external users
        auth
                .ldapAuthentication()
                .userSearchFilter("(&(sAMAccountName={0})(objectClass=person))")
                .contextSource()
                .url(ldapUrls + ldapBaseDn)
                .managerDn(ldapSecurityPrincipal)
                .managerPassword(ldapPrincipalPassword)
                .and()
                .userDnPatterns(ldapUserDnPattern);

    }

РЕДАКТИРОВАТЬ: я выяснил, как создать пользователя и роли, как только пользователь аутентифицируется с LDAP, путем создания Custom ldapAuthoritiesPopulator, который выполняется, но я все еще перенаправлен на страницу whitelabel после входа в системув, как будто пользователь не имеет соответствующей роли для доступа к этой странице. Мой новый код:



@Component
public class CustomLdapAuthoritiesPopulator implements LdapAuthoritiesPopulator {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private UserService userService;

    @Autowired
    private RoleRepository roleRepository;

    @Override
    public Collection<? extends GrantedAuthority> getGrantedAuthorities(
            DirContextOperations userData, String username) {
        Collection<GrantedAuthority> roles = new HashSet<GrantedAuthority>();
        usuário
        if(userRepository.findByUsername(username + "@cpqd.com.br") == null) {
            UserDTO userDTO = new UserDTO();
            userDTO.setUsername(username + "@cpqd.com.br");
            userDTO.setRoles("USER");
            userService.save(userDTO);
            roles.add(new SimpleGrantedAuthority("USER"));
        } else {
            Set<RoleVO> rolesvo = userRepository.findByUsername(username + "@cpqd.com.br").getRoles();
            for (RoleVO role: rolesvo) {
                roles.add(new SimpleGrantedAuthority(role.getName()));
            }
        }

        return roles;
    }
}

Обновлен класс WebSecurityConfig: (пришлось создать экземпляр CustomLdapAuthoritiesPopulator, потому что я получил исключение BeanCurrentlyInCreationException, не уверен, стоит ли вообще это делать)

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Value("${ldap.urls}")
    private String ldapUrls;

    @Value("${ldap.base.dn}")
    private String ldapBaseDn;
    @Value("${ldap.username}")
    private String ldapSecurityPrincipal;
    @Value("${ldap.password}")
    private String ldapPrincipalPassword;
    @Value("${ldap.user.dn.pattern}")
    private String ldapUserDnPattern;

    @Autowired
    private AuthenticationSuccessHandlerImpl successHandler;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;

    @Bean
    public LdapAuthoritiesPopulator getLdapAuthoritiesPopulator() {
        return new CustomLdapAuthoritiesPopulator();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
    }

    @Bean
    public AuthenticationManager customAuthenticationManager() throws Exception {
        return authenticationManager();
    }

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }

    @Bean
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static ServletListenerRegistrationBean httpSessionEventPublisher() {
        // notified when the session is destroyed
        return new ServletListenerRegistrationBean(new HttpSessionEventPublisher());
    }



    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/css/**", "/img/**", "/js/**", "/webjars/**").permitAll()
                .antMatchers("/user/updatePassword*").hasAuthority("CHANGE_PASSWORD_PRIVILEGE")
                .antMatchers("/login", "/register/**", "/user/**").permitAll()
                .antMatchers("/createUser").hasAnyAuthority("CLIENT","ADMIN")
                .anyRequest().hasAuthority("USER")
                .and()
            .formLogin()
                .loginPage("/login")
                .successHandler(successHandler)
                .permitAll()
                .and()
            .logout()
                .invalidateHttpSession(true)
                .deleteCookies("JSESSIONID")
                .and()
            .csrf()
                .disable();

        http.sessionManagement().maximumSessions(3).maxSessionsPreventsLogin(true).sessionRegistry(sessionRegistry());
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth
                .ldapAuthentication()
                .ldapAuthoritiesPopulator(getLdapAuthoritiesPopulator())
                .userSearchFilter("(&(sAMAccountName={0})(objectClass=person))")
                .contextSource()
                .url(ldapUrls + ldapBaseDn)
                .managerDn(ldapSecurityPrincipal)
                .managerPassword(ldapPrincipalPassword)
                .and()
                .userDnPatterns(ldapUserDnPattern);
        auth
                .authenticationProvider(customAuthenticationProvider);

    }


}

EDIT2: Iосознай мою проблему сейчас. Я рассматривал разрешения LDAP как роли, а разрешения пользователей базы данных как полномочия. Если я переключаю .anyRequest () на .hasRole («USER»), происходит обратное, когда пользователи базы данных получают ошибку разрешения, а пользователи LDAP получают доступ. Видимо моя ошибка в реализации разрешений по-разному для каждого типа пользователя

...