我有多项目Spring应用程序。 项目A-负责LDAP身份验证 项目B-负责数据库身份验证 主项目-可以同时使用它们之一或其中之一。 如果仅使用项目A-我们具有LDAP身份验证 如果仅使用项目B-我们具有JDBC身份验证 如果我们同时使用它们-首先进行LDAP认证,如果失败,则进行JDBC认证。而且如果包含了项目B,它会添加一些过滤器
Project MAIN没有@Configuration文件,但是Project A和B有它。
项目A @Configuration
@Configuration
@EnableWebSecurity
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
/**адрес сервера LDAP*/
@Value("${ldap.server}")
private String ldapServer;
/**номер порта LDAP сервера*/
@Value("${ldap.port}")
private int ldapPort;
/**домен для LDAP*/
@Value("${ldap.suffix}")
private String suffix;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(adAuthProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
.authorizeRequests().antMatchers("/**").authenticated()
.and()
.csrf().disable();
}
/**провайдер для аутентификации через LDAP*/
@Bean
public ActiveDirectoryLdapAuthenticationProvider adAuthProvider() {
String ldapUrl = String.format("ldap://%s:%s", ldapServer, ldapPort);
ActiveDirectoryLdapAuthenticationProvider adAuthProvider = new
ActiveDirectoryLdapAuthenticationProvider(suffix, ldapUrl);
adAuthProvider.setConvertSubErrorCodesToExceptions(true);
adAuthProvider.setUseAuthenticationRequestCredentials(true);
return adAuthProvider;
}
}
和项目B配置文件。
@Configuration
@EnableWebSecurity
public class ECommonConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(jdbcAuthProvider());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
.authorizeRequests().antMatchers("/**").authenticated()
.and()
.csrf().disable();
http.addFilterAt(ldapAuthenticationFilter(), LDAPAuthenticationFilter.class);
http.authorizeRequests().antMatchers("/**").access("@requestAuthorization.checkRequestPermissions(authentication, request)");
}
/**провайдер для аутентификации через базу данных*/
@Bean
public DaoAuthenticationProvider jdbcAuthProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
/**бин для шифрования паролей*/
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
/**бин для фильтра проверки наличия LDAP-пользователя в базе данных*/
@Bean
public LDAPAuthenticationFilter ldapAuthenticationFilter() throws Exception {
return new LDAPAuthenticationFilter(authenticationManager());
}
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
/**бин для инициализации базы данных по умолчанию - описание параметров подключения к БД в файле application.yml*/
@Bean
public DataSource dataSource() {
return datasourceConnectionManager().getDataSource("test");
}
/**бин создания менеджера подключения к нескольким базам данных*/
@Bean
public DatasourceConnectionManager datasourceConnectionManager() {
return new DatasourceConnectionManager();
}
}
我需要这两种配置可以一起使用,或者只有一种可以使用它们
答案 0 :(得分:0)
要结合这两种身份验证方式,您可以创建一个自定义身份验证提供程序(更多详细信息,请点击https://www.baeldung.com/spring-security-authentication-provider)
auth提供程序的实现如下所示:
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
private ActiveDirectoryLdapAuthenticationProvider ldapAuthenticationProvider;
private DaoAuthenticationProvider daoAuthenticationProvider;
// env variable to help you choose which auth provider should be enabled
@Value("${ldap.enabled}")
private int ldapEnabled;
// env variable to help you choose which auth provider should be enabled
@Value("${daoAuth.enabled}")
private int daoAuthEnabled;
@Autowired
public CustomAuthenticationProvider(ActiveDirectoryLdapAuthenticationProvider ldapAuthenticationProvider, DaoAuthenticationProvider daoAuthenticationProvider) {
this.ldapAuthenticationProvider = ldapAuthenticationProvider;
this.daoAuthenticationProvider = daoAuthenticationProvider;
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication);
// if both enabled then first try with ldap, if not successful try with dao
if (ldapEnabled && daoAuthEnabled ) {
Authentication authenticate = ldapAuthenticationManager.authenticate(authentication);
if(!authenticate.isAuthenticated()) {
authenticate = ldapAuthenticationManager.authenticate(authentication);
}
return authenticate;
}
// if only ldap enabled
if(ldapEnabled) {
return ldapAuthenticationManager.authenticate(authentication);
}
// if only dao enabled
return daoAuthenticationProvider.authenticate(authentication);
}
@Override
public boolean supports(Class<?> authentication) {
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication);
}
}
答案 1 :(得分:-1)
您可以为此使用Spring分析。只需在配置类上添加@Profile批注以及名称,如下所示。 ProjectA的配置
@Profile("ProjectA")
@Configuration
@EnableWebSecurity
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
和ProjectB的配置
@Profile("ProjectB")
@Configuration
@EnableWebSecurity
public class ECommonConfig extends WebSecurityConfigurerAdapter {
...
然后,在执行应用程序时,可以通过将以下参数传递给java来指定活动配置文件。
#In case of need of only ProjectA then
-Dspring.profiles.active=ProjectA
#In case of need of only ProjectB then
-Dspring.profiles.active=ProjectB
#In case of need of both projects then
-Dspring.profiles.active=ProjectA,ProjectB
您可以使用必需的配置文件在application.properties文件中定义相同的内容
spring.profiles.active=ProjectA,ProjectB
通过这种方式,您可以动态决定应包括哪些项目配置。