Как управлять сеансом с пружинной безопасностью в зависимости от типа запроса? - PullRequest
1 голос
/ 02 октября 2019

Я хотел бы настроить уровень веб-безопасности на основе моего типа запроса.

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

Я попробовал приведенный ниже код.

@Override
protected void configure(HttpSecurity http) throws Exception 
{
    http
        .authorizeRequests()
        .antMatchers("/rest/**").hasRole("SUPER_ADMIN") 
        .anyRequest().fullyAuthenticated()
        .and()
        .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .httpBasic()
        .authenticationEntryPoint(authenticationEntryPoint)
        .and()
        .formLogin().and().logout().permitAll();
}

Он работает с базовой аутентификацией, но не работает для запроса входа в систему, потому что сеансне с состоянием. Может кто-нибудь, пожалуйста, помогите мне настроить безопасность Spring. Я новичок в безопасности Spring.

Ответы [ 2 ]

1 голос
/ 03 октября 2019

Вам необходимо
1. Аутентификация API-интерфейсов остальных пользователей с помощью обычной аутентификации
2. Аутентификация вашего веб-приложения с помощью формы входа.
И авторизация - это другая часть в обоих случаях, которую вы можете установить согласноВаше требование.

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

Теперь перейдем к первому требованию о достижении точки входа с множественной аутентификацией.
1. Для ресурсов API отдыха - аутентификация с помощьюHttpBasicAuthentication для antMatcher /rest/**
2. Для ресурсов WebApp - аутентификация по форме Вход в систему для antMatcher, отличных от /rest/**

Для достижения этой цели
1. Вам необходимо реализовать WebSecurityConfigurerAdapter другого порядка конфигурации и разных шаблонов antMatcher.
2. Порядок каждой конфигурации важен.
- шаблон подстановочного знака (/**) должен быть размещен в последнем порядке
- шаблон без подстановочного знака или шаблон ограниченного доступа (/rest/**) должен быть размещен в первом порядке
3. Поскольку эти классы конфигурации являются статическими, а внутренние классы дляКласс, который аннотирован @EnableWebSecurity, вы должны быть осторожны при определении bean-компонента с использованием @bean и автоматического подключения с использованием @Autowired.

Примечание:
Большинство людей совершает ошибку, не определяя antmather для authorizeRequest ()
Если первая конфигурация @Order(1) класс настроен, как показано ниже
http.authorizeRequests()
2-я конфигурация станет мертвой конфигурацией, потому что
http.authorizeRequests() => http.antMatcher("/**").authorizeRequests()
И все URL будут настроены только для первой конфигурации.

Обратитесь к приведенному ниже коду для лучшего понимания.

@Configuration
@EnableWebSecurity
public class SpringSecurityConfiguration
{
    @Bean
    public PasswordEncoder passwordEncoder() 
    {
        return new BCryptPasswordEncoder();
    }

    @Configuration
    @Order(1)
    public static class BasicAuthSecurityConfig extends WebSecurityConfigurerAdapter
    {
        @Autowired
        private PasswordEncoder passwordEncoder;

        @Autowired
        public void configureInMemoryAuthentication(AuthenticationManagerBuilder auth) throws Exception
        {
            auth.inMemoryAuthentication()
                    .withUser("superadmin")
                    .password(passwordEncoder.encode("superadmin@123#"))
                    .roles("SUPER_ADMIN");
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception
        {
            http.csrf().disable()
                .antMatcher("/rest/**")
                    .authorizeRequests()
                .antMatchers("/rest/**").hasRole("SUPER_ADMIN")
            .and().httpBasic();

            http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        }
    }

    @Configuration
    @Order(2)
    public static class LoginFormSecurityConfig extends WebSecurityConfigurerAdapter
    {
        @Autowired
        private PasswordEncoder passwordEncoder;

        @Autowired
        public void configureInMemoryAuthentication(AuthenticationManagerBuilder auth) throws Exception
        {
            auth.inMemoryAuthentication()
                    .withUser("user")
                    .password(passwordEncoder.encode("user@123#"))
                    .roles("USER");
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception
        {
            http
                .antMatcher("/**") //wild card i.e, allow all (But already /rest/** is filtered by 1st config)
                    .authorizeRequests()
                .antMatchers("/resources/**").permitAll()
                .antMatchers("/**").authenticated()
            .and().formLogin()
                .defaultSuccessUrl("/app/user/dashboard")
            .and().exceptionHandling()
                .accessDeniedPage("/403")
            .and().logout()
                .invalidateHttpSession(true);

            http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired");
        }
    }
}

Для этого вопроса требуетсяразные наборы URL (/rest/** и other than /rest/**) для разных фильтров аутентификации. Здесь пользователь (как для базовой аутентификации, так и для входа в систему) может быть аутентифицирован по одной таблице (скажем, user_details) или нескольким таблицам (скажем, api_users и web_users)

Если у вас есть требование, как будто нет другойнабор URL, но два набора пользователей говорят, что customer и employees (staff) оба обращаются к одному и тому же приложению, но их необходимо аутентифицировать по разным таблицам (скажем, по пользователям и по таблице клиентов), в этом случае см. мой другой ответ Проверка подлинности пользователя Spring Security по таблице клиентов и сотрудников

0 голосов
/ 02 октября 2019

Вы должны разрешить пользователям доступ к странице входа без аутентификации, и то же самое вы можете сделать со статическими страницами. Смотрите конфигурацию ниже.

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/", "/home").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
                .loginPage("/login")
                .permitAll()
                .and()
            .logout()
                .permitAll();
    }

    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        UserDetails user =
             User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build();

        return new InMemoryUserDetailsManager(user);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...