Рубрики
Без рубрики

Две страницы входа в систему с защитой Spring

Краткое и практическое руководство по настройке Spring Security с двумя отдельными страницами входа в систему.

Автор оригинала: baeldung.

1. введение

В этом уроке мы увидим, как мы можем настроить Spring Security для работы с двумя разными страницами входа используя два разных элемента Spring Security http в конфигурации.

2. Настройка 2 Элементов Http

Одна из ситуаций, в которой нам могут понадобиться две страницы входа, – это когда у нас есть одна страница для администраторов приложения и другая страница для обычных пользователей.

Мы настроим два http элемента , которые будут различаться по шаблону URL, связанному с каждым:

  • /user* для страниц, для доступа к которым потребуется обычная аутентификация пользователя
  • /admin* для страниц, к которым будет обращаться администратор

Каждый элемент http будет иметь другую страницу входа и другой URL-адрес обработки входа.

Чтобы настроить два разных элемента http , давайте создадим два статических класса с аннотациями @Configuration , которые расширяют WebSecurityConfigurerAdapter .

Оба будут помещены в обычный класс @Configuration :

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    ...
}

Давайте определим WebSecurityConfigurerAdapter для “АДМИНИСТРАТОРА” пользователей:

@Configuration
@Order(1)
public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter {
    public App1ConfigurationAdapter() {
        super();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/admin*")
          .authorizeRequests()
          .anyRequest()
          .hasRole("ADMIN")
          
          .and()
          .formLogin()
          .loginPage("/loginAdmin")
          .loginProcessingUrl("/admin_login")
          .failureUrl("/loginAdmin?error=loginError")
          .defaultSuccessUrl("/adminPage")
          
          .and()
          .logout()
          .logoutUrl("/admin_logout")
          .logoutSuccessUrl("/protectedLinks")
          .deleteCookies("JSESSIONID")
          
          .and()
          .exceptionHandling()
          .accessDeniedPage("/403")
          
          .and()
          .csrf().disable();
    }
}

А теперь давайте определим WebSecurityConfigurerAdapter для обычных пользователей:

@Configuration
@Order(2)
public static class App2ConfigurationAdapter extends WebSecurityConfigurerAdapter {

    public App2ConfigurationAdapter() {
        super();
    }

    protected void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/user*")
          .authorizeRequests()
          .anyRequest()
          .hasRole("USER")
          
          .and()
          .formLogin()
          .loginPage("/loginUser")
          .loginProcessingUrl("/user_login")
          .failureUrl("/loginUser?error=loginError")
          .defaultSuccessUrl("/userPage")
          
          .and()
          .logout()
          .logoutUrl("/user_logout")
          .logoutSuccessUrl("/protectedLinks")
          .deleteCookies("JSESSIONID")
          
          .and()
          .exceptionHandling()
          .accessDeniedPage("/403")
          
          .and()
          .csrf().disable();
    }
}

Обратите внимание, что, помещая аннотацию @Order в каждый статический класс, мы указываем порядок, в котором два класса будут рассматриваться на основе сопоставления шаблонов при запросе URL-адреса.

Два класса конфигурации не могут иметь одинаковый порядок.

3. Пользовательские Страницы Входа В Систему

Мы создадим ваши собственные страницы входа для каждого типа пользователей. Для пользователя-администратора форма входа в систему будет иметь действие “user_login” , как определено в конфигурации:

User login page

User:
Password:

Страница входа администратора аналогична, за исключением того, что форма будет иметь действие “admin_login” в соответствии с конфигурацией java.

4. Конфигурация аутентификации

Теперь нам нужно настроить аутентификацию для нашего приложения . Давайте рассмотрим два способа достижения этой цели — один с использованием общего источника для аутентификации пользователей, а другой с использованием двух отдельных источников.

4.1. Использование общего источника аутентификации пользователя

Если обе страницы входа имеют общий источник для аутентификации пользователей, вы можете создать один компонент типа UserDetailsService , который будет обрабатывать аутентификацию.

Давайте продемонстрируем этот сценарий с помощью InMemoryUserDetailsManager , который определяет двух пользователей — одного с ролью “ПОЛЬЗОВАТЕЛЬ” и одного с ролью “АДМИНИСТРАТОР” :

@Bean
public UserDetailsService userDetailsService() throws Exception {
    InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
    manager.createUser(User
      .withUsername("user")
      .password(encoder().encode("userPass"))
      .roles("USER")
      .build());
    
    manager.createUser(User
      .withUsername("admin")
      .password(encoder().encode("adminPass"))
      .roles("ADMIN")
      .build());
    
    return manager;
}

@Bean
public static PasswordEncoder encoder() {
    return new BCryptPasswordEncoder();
}

4.2. Использование Двух Разных Источников Аутентификации Пользователей

Если у вас есть разные источники для аутентификации пользователей — один для администраторов и один для обычных пользователей, — вы можете настроить AuthenticationManagerBuilder внутри каждого статического @Configuration класса. Давайте рассмотрим пример менеджера аутентификации для пользователя “АДМИНИСТРАТОР” :

@Configuration
@Order(1)
public static class App1ConfigurationAdapter extends WebSecurityConfigurerAdapter { 
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
          .withUser("admin")
          .password(encoder().encode("admin"))
          .roles("ADMIN");
    }
}

В этом случае компонент UserDetailsService из предыдущего раздела больше не будет использоваться.

6. Заключение

В этом кратком руководстве мы показали, как реализовать две разные страницы входа в одно и то же приложение Spring Security.

Полный код этой статьи можно найти в проекте GitHub .

При запуске приложения вы можете получить доступ к приведенным выше примерам по /защищенным ссылкам URI.