У меня есть приложение, которое использует 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 получают доступ. Видимо моя ошибка в реализации разрешений по-разному для каждого типа пользователя