Как заставить Spring Security работать в юнит-тестах? - PullRequest
1 голос
/ 27 октября 2019

Я пытаюсь понять, как протестировать приложение Spring Boot со слоем Spring Security.

Я задавал похожие вопросы Как применить Spring Security с MockitoJUnit бегуном? и Как смоделировать детали обслуживания клиентов в слое Spring Security?

  1. У меня есть пользовательская реализация для UserDetailsService, которая принимаетданные из базы данных, поэтому, естественно, я хочу взять их откуда-то еще на этапе юнит-тестирования

  2. Я хочу проверить свой веб-слой, чтобы увидеть, работает ли Spring Security ивсе другие варианты использования также работают.

Как мне выполнить обе вышеуказанные задачи?

SecurityConfig класс:

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String[] AUTH_WHITELIST = {
            // -- swagger ui
            "/",
            "/csrf",
            "/swagger-resources",
            "/swagger-resources/**",
            "/configuration/ui",
            "/configuration/security",
            "/swagger-ui.html",
            "/webjars/**"
    };

    @Autowired
    @Qualifier("customUserDetailsService")
    private UserDetailsService userDetailsService;

    private final static Integer bCryptEncryptionLevel = 8;

    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder(bCryptEncryptionLevel);
    }

    public SecurityConfig() {
        super();
    }

    @Autowired
    public void configureGlobalSecurity(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
        authManagerBuilder.authenticationProvider(authenticationProvider());
        authManagerBuilder.userDetailsService(userDetailsService)
                .passwordEncoder(bCryptPasswordEncoder());
    }

    @Bean
    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(bCryptPasswordEncoder());
        return authenticationProvider;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                    .antMatchers(AUTH_WHITELIST).permitAll()
                    // allow default swagger docket
                    .regexMatchers("\\A/v2/api-docs\\Z").permitAll()
                    // require auth for any other swagger docket
                    .regexMatchers("\\A/v2/api-docs?.*\\Z").authenticated()
                    .antMatchers("/**").authenticated()
                .and()
                .httpBasic()
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}

CustomUserDetailsService класс:

@Service("customUserDetailsService")
@Profile("!test")
public class CustomUserDetailsService implements UserDetailsService {
    private final static Logger logger = LoggerFactory.getLogger(CustomUserDetailsService.class);

    private StringRedisTemplate redisTemplate;
    private RedisProperties redisProperties;

    @Autowired
    public CustomUserDetailsService(RedisProperties redisProperties, StringRedisTemplate redisTemplate) {
        this.redisProperties = redisProperties;
        this.redisTemplate = redisTemplate;
    }


    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        // Do queries to DB and return user if such user exists
    }
}

Я также добавил CustomUserDetailsServiceTest класс для модульного тестирования только в тот же пакет, но под src/test/java:

@Service("customUserDetailsService")
@Profile("test")
public class CustomUserDetailsServiceTest implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        @SuppressWarnings("serial")
        Map<Object, Object> entries = new HashMap<Object, Object>(){{
            put("username", username);
            put("password_hash", "$2a$08$YjMcOsLmbbUB4DYPxqSAxOa3STLjEDovwd2..Uidwp.asyhSi8Y5u");
            put("role", "ADMIN");
        }};
        UserEntity user = new UserEntity(entries);
        return new HiccasoftApiUser(user);
    }
}

Как я могу использоватьпользовательская реализация customUserDetailsService в юнит-тестах при тестировании веб-слоя?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...