Здравствуйте!
Я реализовал это следующим образом:
В данном случае у меня 2 кастомные формы входа:
1) для админ панели /admin/login
2) для пользователей /auth
/**
* Конфигурация для Spring Security
*/
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig {
private static UserDetailsServiceImpl userDetailsService;
@Autowired
private UserDetailsServiceImpl userDetailsServiceImpl;
@PostConstruct
private void init() {
userDetailsService = this.userDetailsServiceImpl;
}
@Bean
public static PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DaoAuthenticationProvider authProvider() {
CustomAuthenticationProvider authProvider = new CustomAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
// Конфигурация для backend
@Configuration
@Order(1)
public static class BackendConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private CustomWebAuthenticationDetailsSource authenticationDetailsSource;
public BackendConfigurationAdapter() {
super();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/admin/**")
.antMatcher("/admin/**/**")
.authorizeRequests()
.anyRequest()
.hasAuthority("ADMIN_PRIVILEGE")
/*.hasAuthority("ADMIN")*/
.and()
.formLogin()
.authenticationDetailsSource(authenticationDetailsSource)
.loginPage("/admin/login")
.loginProcessingUrl("/admin/login")
.usernameParameter("email")
.passwordParameter("password")
.defaultSuccessUrl("/admin/dashboard")
.failureUrl("/admin/login?authError")
.permitAll()
.and()
.rememberMe()
.rememberMeParameter("remember-me")
.tokenValiditySeconds(86400)
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/admin/logout"))
.logoutSuccessUrl("/admin/login")
.deleteCookies("JSESSIONID")
.and()
.exceptionHandling()
.accessDeniedPage("/403")
.and()
.csrf()
.ignoringAntMatchers("/admin/**");
}
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers(
// статика backend
"/backend/css/**",
"/backend/js/**",
"/backend/fonts/**",
"/backend/images/**",
"/backend/init/**"
);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
}
// Конфигурация для frontend (Обычная авторизация и авторизация oauth2)
@Configuration
@Order(2)
public static class FrontendConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Autowired
private CustomWebAuthenticationDetailsSource authenticationDetailsSource;
public FrontendConfigurationAdapter() {
super();
}
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().mvcMatchers("/robots.txt").permitAll()
.antMatchers(
"/", "/auth", "/signup", "/restore", "/activation/**",
"/admin/login", "/admin_restore",
"/attachments/get/**",
"/sendMessage",
"/error",
"/page/**",
"/categories", "/categories/**",
"/terms/**", "/posts", "/posts/**"
).permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.authenticationDetailsSource(authenticationDetailsSource)
.loginPage("/auth")
.loginProcessingUrl("/auth")
.usernameParameter("email")
.passwordParameter("password")
.defaultSuccessUrl("/")
.failureUrl("/auth?authError")
.permitAll()
.and()
.rememberMe()
.rememberMeParameter("remember-me")
.tokenValiditySeconds(86400)
.and()
.oauth2Login().defaultSuccessUrl("/")
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/")
.deleteCookies("JSESSIONID")
.and()
.exceptionHandling()
.accessDeniedPage("/403")
.and()
.csrf()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
.and()
.headers().frameOptions().sameOrigin();
}
@Override
public void configure(WebSecurity web) {
web.ignoring().antMatchers(
"/frontend/css/**",
"/frontend/js/**",
"/frontend/fonts/**",
"/frontend/images/**",
"/frontend/lib/**",
"/frontend/vendor/**"
);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
}
}
Админа, как по мне, лучше создать при инициализации приложения. Вот, код, как это делаю я.
@Component
public class InitData implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
if (userServiceImpl.usersCount() == 0)
initUsers();
}
private void initUsers() {
// создаем пользователей
}
}