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;