Search code examples
javaspringspring-security

permit for mvc controller in spring security


In method I need return page with info(else-condition):

    public String createInvoice(String request, MerchantRequestInfo merchantRequestInfo) {
        if (isPaymentAvailable) {
        return invoiceClient.createInvoice(request, merchantRequestInfo).bodyToMono(String.class).block();
        } else {
            return "localhost:8080/invoice-result?RC=503";
        }
    }

It's redirect to MVC controller-blank:

    @Slf4j
    @Controller
    @RequiredArgsConstructor
    public class PaymentNotAvailableController {

        @RequestMapping({"/invoice-result"})
        public String failedInvoiceForm(@RequestParam Map<String, String> params) {
            return "forward:index.html";
        }
    }

Problem is, that Spring Security blocking this controller request, and in response link I get page:

"access deny for localhost"

Here Spring Security config:

@Configuration
@RequiredArgsConstructor
public class SecurityConfig {

    @Bean
    @Order(1)
    public SecurityFilterChain apiSecurityFilterChain(HttpSecurity http,
                                                      MerchantAuthenticationProvider merchantAuthenticationProvider,
                                                      MerchantAuthenticationConverter merchantAuthenticationConverter,
                                                      MerchantAuthenticationSuccessHandler merchantAuthenticationSuccessHandler,
                                                      MerchantAccessDeniedHandler merchantAccessDeniedHandler,
                                                      MerchantAuthenticationEntryPoint merchantAuthenticationEntryPoint) throws Exception {
        var merchantAuthenticationFilter = new AuthenticationFilter(new ProviderManager(merchantAuthenticationProvider),
                merchantAuthenticationConverter);
        merchantAuthenticationFilter.setFailureHandler(merchantAuthenticationEntryPoint);
        merchantAuthenticationFilter.setSuccessHandler(merchantAuthenticationSuccessHandler);
        return http
                .securityMatcher("/api/**")
                .csrf(AbstractHttpConfigurer::disable)
                .cors(AbstractHttpConfigurer::disable)
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeHttpRequests(auth -> auth
                        .anyRequest().authenticated())
                .addFilterBefore(merchantAuthenticationFilter, BasicAuthenticationFilter.class)
                .exceptionHandling(handler -> handler
                        .accessDeniedHandler(merchantAccessDeniedHandler)
                        .authenticationEntryPoint(merchantAuthenticationEntryPoint))
                .build();
    }

    @Bean
    @Order(10)
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        return http
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/swagger-ui.html", "/v3/api-docs/**", "/swagger-ui/**", "/webjars/swagger-ui/**").permitAll()
                        .requestMatchers("/actuator/**", "/schemas/**", "/invoice-result").permitAll()
                        .anyRequest().authenticated())
                .build();
    }
}

If I comment // method apiSecurityFilterChain, it is work normal.

I tried put "/invoice-result").permitAll() for my controller, but no result.

Frontend and backend is locate in one service.


Solution

  • .requestMatchers("/actuator/**", "/schemas/**", "/**").permitAll()
    

    I put /**, it solved the problem.