我有一个现有项目,该项目正在使用带有Spring Security的InMemory身份验证,现在有一个新要求。现在,我们还需要将基于数据库的身份验证与InMemory身份验证一起使用,因为将有两种类型的用户:一种是静态的,另一种是动态添加的;另一种是动态添加。对于动态添加,我们需要使用基于数据库的身份验证。我在不同的项目中都使用了InMemory和基于数据库的身份验证,但在同一项目中没有都使用过。 请提出在同一项目上同时使用两者的一些解决方案。我使用的是Spring Boot 2.0.2Release,欢迎使用基于Java的解决方案。
@Configuration
@EnableWebSecurity
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Value("${admin.username}")
String user;
@Value("${admin.password}")
String password;
@Value("${superadmin.username}")
String admin;
@Value("${superadmin.password}")
String adminPassword;
/* (non-Javadoc)
* @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/","/blogs","/support","/index","/pricing","/step-guide","/sales-info","/sales-info/**","/step-guide/**","/blogs/**","/productdetail","/25-point-checklist-for-networking","/thanks-for-downloading-checklist","/events-&-conference",,"/share_profile","/share","/share/**").permitAll()
.antMatchers("/swagger-ui.html").hasAnyAuthority("ROLE_SUPER_ADMIN")
.antMatchers("/admin").hasAnyAuthority("ROLE_SUPER_ADMIN","ROLE_ADMIN")
.antMatchers("/api/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").permitAll()
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
String currentUsername = authentication.getName();
if(currentUsername.equals(admin)) {
response.sendRedirect(request.getContextPath()+"/admin");
}
else if(currentUsername.equals(user))
{
response.sendRedirect(request.getContextPath()+"/swagger-ui.html");
}
}
})
.and()
.logout()
.permitAll()
.and().csrf().disable();
}
/* (non-Javadoc)
* @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder)
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser(user)
.password(PasswordUtil.encryptPassword(password))
.credentialsExpired(false)
.accountExpired(false)
.accountLocked(false)
.roles("SUPER_ADMIN");
auth.inMemoryAuthentication()
.withUser(admin)
.password(PasswordUtil.encryptPassword(adminPassword))
.credentialsExpired(false)
.accountExpired(false)
.accountLocked(false)
.roles("ADMIN");
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**","/webjars/**","/static/**","/css/**","/js/**","/fonts/**","/images/**","/favicon.ico","/swagger-resources/**","/bucket/**");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
具有数据库身份验证和自定义身份验证处理程序的代码是:
@Configuration
@EnableWebSecurity
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SecurityConfig extends WebSecurityConfigurerAdapter{
@Autowired
PasswordEncoder passwordEncoder;
@Autowired
AppUserDetailsService appUserDetailsService;
@Autowired
CustomAuthenticationSuccessHandler customAuthenticationSuccessHandler;
/* (non-Javadoc)
* @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder)
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(appUserDetailsService).passwordEncoder(passwordEncoder);
}
/* (non-Javadoc)
* @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.WebSecurity)
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**","/webjars/**","/static/**","/css/**","/js/**","/fonts/**","/images/**","/favicon.ico");
}
/* (non-Javadoc)
* @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/swagger-ui.html").hasAnyAuthority("ROLE_SUPER_ADMIN")
.antMatchers("/api/user/sign_up").permitAll()
.antMatchers("/api/user/forgot_password").permitAll()
.antMatchers("/api/**").authenticated()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login").successHandler(customAuthenticationSuccessHandler).permitAll()
.and()
.logout()
.permitAll()
.and().csrf().disable().exceptionHandling().accessDeniedPage("/403");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
所以我想将两者结合起来,根据情况,它可以有一个登录页面或多个登录页面。
答案 0 :(得分:1)
如果实现WebSecurityConfigurerAdapter,则具有以下功能:
@Override
protected void configure(AuthenticationManagerBuilder auth) {
// auth.ldapAuthentication()...
auth.apply(new LdapAuthenticationProviderConfigurer());
auth.apply(new JdbcUserDetailsManagerConfigurer<>());
auth.apply(new InMemoryUserDetailsManagerConfigurer<>());
}
方法ldapAuthentication()除了将LdapAuthenticationProvider添加到AbstractConfiguredSecurityBuilder的配置列表之外,什么也不做。 只需尝试将另一个配置器添加到AuthenticationManagerBuilder。
示例:
InMemoryUserDetailsManagerConfigurer memprovider =
new InMemoryUserDetailsManagerConfigurer();
memprovider.withUser("admin")
.credentialsExpired(false)
.accountExpired(false)
.accountLocked(false)
.roles("SUPER_ADMIN");
auth.apply(memprovider);
这将应用新的提供者。而不是简单地应用第二个:
JdbcUserDetailsManagerConfigurer jdpbProvider =
new JdbcUserDetailsManagerConfigurer();
jdpbProvider.withUser("user").password() ...
auth.apply(jdpbProvider);
使用UserDetailService:
@Autowired
UserDetailsService appUserDetailsService;
和
DaoAuthenticationConfigurer daoAC =
new DaoAuthenticationConfigurer(appUserDetailsService);
daoAC.passwordEncoder(passwordEncoder);
auth.apply(daoAC);
答案 1 :(得分:0)
您可以在Spring安全性中使用org.springframework.security.authentication.ProviderManager
,并将数据库和InMemory用作providers
。
答案 2 :(得分:0)
以下设置适用于您的情况:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
DaoAuthenticationProvider daoAuth = new DaoAuthenticationProvider();
daoAuth.setUserDetailsService(appUserDetailsService);
daoAuth.setPasswordEncoder(passwordEncoder);
auth.authenticationProvider(daoAuth);
auth.inMemoryAuthentication()
.withUser(user)
.password(PasswordUtil.encryptPassword(password))
.credentialsExpired(false)
.accountExpired(false)
.accountLocked(false)
.roles("SUPER_ADMIN");
auth.inMemoryAuthentication()
.withUser(admin)
.password(PasswordUtil.encryptPassword(adminPassword))
.credentialsExpired(false)
.accountExpired(false)
.accountLocked(false)
.roles("ADMIN");
}