访问内存数据库时如何绕过Ldap的认证过程
How to bypass the authentication process of Ldap while accessing in-memory database
我开发了一个登录页面,其中用户可以是来自活动目录 (LDAP) 的用户或来自基于文件的 H2 数据库的本地用户或来自已存储凭据的配置文件的用户,例如用户名 - admin , 密码 - admin.
在配置文件中提供了启用或禁用 LDAP、内存和 H2 数据库身份验证的选项。
假设启用了所有 3 种类型的身份验证,并且来自 H2 数据库的本地用户登录,因此根据逻辑,因为启用了所有 3 种类型的身份验证,所以在所有 3 个数据库中进行检查,即活动目录、内存和 H2 数据库(如果用户存在或不存在)应避免使用。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger _LOG = LoggerFactory.getLogger(SecurityConfig.class);
private ActiveDirectoryLdapAuthenticationProvider provider;
@Autowired
private DataSource dataSource;
@Autowired
private PasswordEncoder bCryptPasswordEncoder;
@Value("${ldap.auth.enabled}")
private boolean ldapAuthEnabled;
@Value("${database.auth.enabled}")
private boolean databaseAuthEnabled;
@Value("${inMemory.auth.enabled}")
private boolean imMemAuthEnabled;
@Value("${userrole.admin.username}")
private String adminUsername;
@Value("${userrole.admin.password}")
private String adminPassword;
@Value("${ldap.domain}")
private String ldapDomain;
@Value("${ldap.url}")
private String ldapUrl;
@PostConstruct
public void configValuesForApplication() {
_LOG.info("Ldap Authentication {}", ldapAuthEnabled);
_LOG.info("In Memory Authentication {} ", imMemAuthEnabled);
_LOG.info("Ldap Authentication {}", ldapAuthEnabled);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http
.authorizeRequests()
.antMatchers(
"/", "/reg",
"/js*//**//**",
"/css*//**//**",
"/img*//**//**",
"/webjars*//**//**").permitAll()
.antMatchers("/user*//**//**").hasRole("USER")
.antMatchers("/admin", "/h2_console/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/index")
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler);
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
if (imMemAuthEnabled) {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser(adminUsername).password(adminPassword).roles("ADMIN");
}
if (databaseAuthEnabled) {
auth.
jdbcAuthentication()
.authoritiesByUsernameQuery("select username, role FROM USER where username=?")
.usersByUsernameQuery("select username,password, 1 FROM USER where username=?")
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
if (ldapAuthEnabled) {
provider = new ActiveDirectoryLdapAuthenticationProvider(ldapDomain, ldapUrl);
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
auth.authenticationProvider(provider);
}
}
}
login.properties 文件如下
ldap.auth.enabled=true
inMemory.auth.enabled=true
database.auth.enabled=true
userrole.admin.username=admin
userrole.admin.password=admin
userrole.user.username=user
userrole.user.password=user
ldap.domain=foo.com
ldap.url=ldap://abcdef12.foo.com.:450/
spring.h2.console.enabled=true
spring.h2.console.path=/h2_console
spring.datasource.url=jdbc:h2:file:~/h2/vehicledb
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
问题是,如果来自 H2 数据库的用户登录,如何避免检查 LDAP 和内存数据库?
您可以编写自己的安全提供程序
此处提供示例:
https://www.baeldung.com/spring-security-multiple-auth-providers
我开发了一个登录页面,其中用户可以是来自活动目录 (LDAP) 的用户或来自基于文件的 H2 数据库的本地用户或来自已存储凭据的配置文件的用户,例如用户名 - admin , 密码 - admin.
在配置文件中提供了启用或禁用 LDAP、内存和 H2 数据库身份验证的选项。
假设启用了所有 3 种类型的身份验证,并且来自 H2 数据库的本地用户登录,因此根据逻辑,因为启用了所有 3 种类型的身份验证,所以在所有 3 个数据库中进行检查,即活动目录、内存和 H2 数据库(如果用户存在或不存在)应避免使用。
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger _LOG = LoggerFactory.getLogger(SecurityConfig.class);
private ActiveDirectoryLdapAuthenticationProvider provider;
@Autowired
private DataSource dataSource;
@Autowired
private PasswordEncoder bCryptPasswordEncoder;
@Value("${ldap.auth.enabled}")
private boolean ldapAuthEnabled;
@Value("${database.auth.enabled}")
private boolean databaseAuthEnabled;
@Value("${inMemory.auth.enabled}")
private boolean imMemAuthEnabled;
@Value("${userrole.admin.username}")
private String adminUsername;
@Value("${userrole.admin.password}")
private String adminPassword;
@Value("${ldap.domain}")
private String ldapDomain;
@Value("${ldap.url}")
private String ldapUrl;
@PostConstruct
public void configValuesForApplication() {
_LOG.info("Ldap Authentication {}", ldapAuthEnabled);
_LOG.info("In Memory Authentication {} ", imMemAuthEnabled);
_LOG.info("Ldap Authentication {}", ldapAuthEnabled);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http
.authorizeRequests()
.antMatchers(
"/", "/reg",
"/js*//**//**",
"/css*//**//**",
"/img*//**//**",
"/webjars*//**//**").permitAll()
.antMatchers("/user*//**//**").hasRole("USER")
.antMatchers("/admin", "/h2_console/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/index")
.permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout")
.permitAll()
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler);
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
if (imMemAuthEnabled) {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER")
.and()
.withUser(adminUsername).password(adminPassword).roles("ADMIN");
}
if (databaseAuthEnabled) {
auth.
jdbcAuthentication()
.authoritiesByUsernameQuery("select username, role FROM USER where username=?")
.usersByUsernameQuery("select username,password, 1 FROM USER where username=?")
.dataSource(dataSource)
.passwordEncoder(bCryptPasswordEncoder);
}
if (ldapAuthEnabled) {
provider = new ActiveDirectoryLdapAuthenticationProvider(ldapDomain, ldapUrl);
provider.setConvertSubErrorCodesToExceptions(true);
provider.setUseAuthenticationRequestCredentials(true);
auth.authenticationProvider(provider);
}
}
}
login.properties 文件如下
ldap.auth.enabled=true
inMemory.auth.enabled=true
database.auth.enabled=true
userrole.admin.username=admin
userrole.admin.password=admin
userrole.user.username=user
userrole.user.password=user
ldap.domain=foo.com
ldap.url=ldap://abcdef12.foo.com.:450/
spring.h2.console.enabled=true
spring.h2.console.path=/h2_console
spring.datasource.url=jdbc:h2:file:~/h2/vehicledb
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
问题是,如果来自 H2 数据库的用户登录,如何避免检查 LDAP 和内存数据库?
您可以编写自己的安全提供程序
此处提供示例:
https://www.baeldung.com/spring-security-multiple-auth-providers