1

I am facing an issue where I can't send a login post request from React front end, even while disabling csrf and cors. I also tried adding cors configuration, I can register new users from the front end but login won't work due to "Access to XMLHttpRequest at 'http://localhost:8080/login' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource." Login works from postman, I suspect this issue has 100% to do with cors.

Any idea how to circumvent this?

I tried disabling cors, adding cors configuration to spring to accept localhost3000, but none of them worked. Here is my code so far:

Websecurity config:

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Autowired
    UserDetailsService userDetailsService;


    @Bean
    public AuthenticationManager authManager(HttpSecurity http) throws Exception {
        AuthenticationManagerBuilder authenticationManagerBuilder =
                http.getSharedObject(AuthenticationManagerBuilder.class);
        authenticationManagerBuilder.authenticationProvider(authenticationProvider());
        authenticationManagerBuilder.userDetailsService(userDetailsService);
        return authenticationManagerBuilder.build();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests((requests) -> requests
                        //permit routes to / and /home
                        .antMatchers("/", "/home", "/signup", "/users", "/login")
                        .permitAll()
                        .anyRequest().
                        authenticated())
                .cors().configurationSource(corsConfigurationSource()).and()
                .csrf()
                .disable()
                .formLogin()
                .defaultSuccessUrl("https://www.apple.com/", true);
        return http.build();
    }

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

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("https://localhost:3000"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

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

Login.js

function Login() {
    const [formData, setFormData] = useState({
        username: '',
        password: ''
    });

    const [usernameError, setUsernameError] = useState('');
    const [passwordError, setPasswordError] = useState('');



    const onUserNameChange = (e) => {
        setFormData({...formData, username: e.target.value})
    }

    const onPasswordChange = (e) => {
        setFormData({...formData, password: e.target.value})
    }

    const login = async (username, password) => {
        const response = await axios.post("http://localhost:8080/login", {
            password: formData.username,
            username: formData.password
        })
    };


    return (
        <Container>
            <Typography variant='h4'>Login</Typography>
            <Stack spacing={2}>
                <TextField label='Username' onChange={onUserNameChange}/>
                {
                    usernameError ? <span style={{ color: 'red', fontSize: '12px'}}>{usernameError}</span> : ''
                }
                <TextField label='Password' type="password" onChange={onPasswordChange}/>
                {
                    passwordError ? <span style={{ color: 'red', fontSize: '12px'}}>{passwordError}</span> : ''
                }
                <Button variant='contained' onClick={login}>Login</Button>
            </Stack>
        </Container>
    );
}

export default Login;

1 Answers1

0

Found a solution that worked for me

on this path of search i found @ this link a solution by adding some additional configurations to corsconfiguration.

 @Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    return http
            .csrf().disable()
            .cors()
            .configurationSource(request-> corsConfigurationSource().getCorsConfiguration(request))
            // .configurationSource(corsConfigurationSource())
            // .disable()
            .and().authorizeHttpRequests()
            // .requestMatchers("/**").authenticated()
            // .requestMatchers("**/admin/**").hasRole("ADMIN")

            .requestMatchers("/**admin**").hasRole(Roles.ADMIN.name())
            .anyRequest().authenticated()
            // .anyRequest().permitAll()
            .and().formLogin()
            .and().httpBasic()
            .and().build();

}

@Bean
public AuthenticationProvider authProvider() {
    DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
    authProvider.setUserDetailsService(userDetailsService());
    authProvider.setPasswordEncoder(passwordEncoder());
    return authProvider;
}

@Bean
CorsConfigurationSource corsConfigurationSource() {
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedHeaders(List.of("Authorization", "Cache-Control", "Content-Type"));
    configuration.setAllowedOrigins(List.of("http://localhost:3000"));
    configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PUT","OPTIONS","PATCH", "DELETE"));
    configuration.setAllowCredentials(true);
    configuration.setExposedHeaders(List.of("Authorization"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}
rista_101
  • 81
  • 1
  • 5