Spring Security Наряду с Cors дает 302 и возвращает страницу входа - PullRequest
0 голосов
/ 17 сентября 2018

Прошло несколько недель с тех пор, как я начал работать с весной, сейчас я пытаюсь расширить свои знания.То, что я пытаюсь сделать, это.

У меня есть приложение Spring MVC, которое использует Spring Security и имеет простую форму входа в систему, и после входа в систему некоторые простые операции CRUD, это работает хорошо, когда я вхожу в приложение, используя форму jsp.

но когда я выполняю аналогичное действие из ANGULAR-приложения, запрос не приземляется и возвращает код состояния 302, тогда делается другой запрос на страницу входа в приложение Spring и возвращается html-имя входа.

ниже приведены классы конфигурации, которые я использую:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired(required = true)
    private UserDetailsService userDetailsService;

    private static final String[] AUTH_WHITELIST = {

            // -- swagger ui
            "/swagger-resources/**", "/swagger-ui.html", "/v2/api-docs",
            "/webjars/**", "/swagger.json", "/swagger*/**", "/user/**" };

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    };

    @Override
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(
                passwordEncoder());
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**");
        web.ignoring().antMatchers("/v2/api-docs/**");
        web.ignoring().antMatchers("/swagger.json");
        web.ignoring().antMatchers("/swagger-ui.html");
        web.ignoring().antMatchers("/swagger-resources/**");
        web.ignoring().antMatchers("/webjars/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and().authorizeRequests().antMatchers(AUTH_WHITELIST)
                .authenticated().anyRequest().permitAll().and()
                .authorizeRequests().anyRequest().hasAnyRole("ADMIN", "USER")
                .and().authorizeRequests().antMatchers("/login**").permitAll()
                .and().formLogin().loginPage("/login")
                .loginProcessingUrl("/loginAction").permitAll().and().logout()
                .logoutUrl("/logout")
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login").permitAll()
                .deleteCookies("JSESSIONID").invalidateHttpSession(true).and()
                .csrf().disable();

        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .maximumSessions(1).expiredUrl("/login.jsp");

    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST",
                "PUT", "DELETE", "PATCH"));

        configuration.setAllowCredentials(false);

        configuration.setAllowedHeaders(Arrays.asList("Authorization",
                "Cache-Control", "Content-Type","X-Requested-With","Access-Control-Allow-Headers","Accept"));

        configuration.addAllowedHeader("*");
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }



}

Другой класс конфигурации с именем WebConfig, который реализует WebMvcConfigurer

@Configuration
@PropertySource("classpath:documentation.properties")
@ComponentScans(value = {
        @ComponentScan(basePackages = { "com.xx.xx.xx" }),
        @ComponentScan("com.xx.xx.xx") })
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureViewResolvers(ViewResolverRegistry registry) {
        registry.jsp().prefix("/WEB-INF/views/").suffix(".jsp");
    }

    @Override
    public void addCorsMappings(CorsRegistry registry) {

        registry.addMapping("/**")
                .allowedOrigins("http://localhost:4200")
                .allowedMethods("PUT", "DELETE")
                .allowedHeaders("Authorization", "Cache-Control",
                        "Content-Type", "X-Requested-With",
                        "Access-Control-Allow-Headers")
                .exposedHeaders("Cache-Control", "Content-Type")
                .allowCredentials(false).maxAge(4800);

        // Add more mappings...
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        // Register resource handler for resources
        registry.addResourceHandler("/resources/**")
                .addResourceLocations("/WEB-INF/resources/")
                .setCacheControl(
                        CacheControl.maxAge(2, TimeUnit.HOURS).cachePublic());

        registry.addResourceHandler("swagger-ui.html").addResourceLocations(
                "classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations(
                "classpath:/META-INF/resources/webjars/");
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
    }
}

И остальной API, я пытаюсьвызов из приложения ANGULAR.

@CrossOrigin(origins = "http://localhost:4200", maxAge = 4800, allowCredentials = "false")
@RestController
public class UserController {
    private static final Class<UserController> className = UserController.class;
    @Autowired
    UserService userService;

    @CrossOrigin
    @PostMapping(value = "/user/authenticate")
    @ApiOperation(value = "Authenticate User", notes = "${UserController.authenticate.notes}")
    public void authenticate(
            @ApiParam(value = "${UserController.authenticate.body}", required = true) @RequestBody String userData,
            HttpServletResponse response) throws IOException {
        System.out.println("called");
        try {
            String result = userService.authenticateUser(userData);
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            response.getWriter().write(result);
        } catch (JSONException e) {
            System.out.println(e.getLocalizedMessage());
        }

    }
}

Я звоню, чтобы подтвердить подлинность API с телом POST.URL-адрес "http://localhost:8080/spring-security-example/user/authenticate". Теперь я буду делиться снимками экрана сетевого трафика при попытке входа в систему из углового приложения.

  1. Экран 1: запрос Original First, но с запросомМетод ORIGIN

  2. Экран 2: Второй запрос, который был отправлен автоматически с методом запроса GET, должен быть POST, я не знаю, где он был изменен

  3. Экран 3:первый запрос на вход в систему JSP, который также не был отправлен мной
  4. Экран 4: последний запрос, в котором вы можете увидеть код login.jsp вернул

The Original First request but with request method ORIGIN

The second reqeust that was sent automatically with request method GET should be POST i dont know where it gets changed

first request to the login jsp which also was not sent by me

last request in which u can see code of login.jsp returned

Теперь, если я удаляю csrf().disable() из HttpSecurity, у меня будет только два запроса на аутентификацию, сначала будет метод запроса ORIGIN, а следующим будет метод запроса POST, но он вернет 403, запрещенных как пружинный блок csrf.запросы, когда csrf включен.

Так что мой вопрос в том, что я делаю здесь неправильно,и почему метод запроса изменяется на GET сам по себе с csrf().disable().

1 Ответ

0 голосов
/ 18 сентября 2018

После изменения моего HttpConfigure Security я заработал, ниже приведен новый код для него.

http.authorizeRequests().antMatchers("/swagger-resources/**", "/swagger-ui.html", "/v2/api-docs",
            "/webjars/**", "/swagger.json", "/swagger*/**", "/user/**").permitAll()
                .antMatchers("/**").authenticated().and().authorizeRequests()
                .anyRequest().hasAnyRole("ADMIN", "USER").and().headers().and()
                .exceptionHandling().and().authorizeRequests()
                .antMatchers("/login**").permitAll().and().formLogin()
                .loginPage("/login").loginProcessingUrl("/loginAction")
                .permitAll().and().logout().logoutUrl("/logout")
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login").permitAll()
                .deleteCookies("JSESSIONID").invalidateHttpSession(true).and()
                .exceptionHandling().and().cors().and().csrf().disable();

Мне кажется, что это был только вопрос конфигурации.Теперь я не получаю в ответ статус 302.

...