What I am trying to achieve
I am trying to implement Spring Security with REST API and React as frontend with basic authentication (I am not planning on using JWT because it is overkill for my project). This is my first time implementing security, so I am feeling a bit lost. I am using Spring Spring Boot 3.2.1 and most of the articles online are deprecated.
What I have done so far
Load users from database using JDBC
@Bean
public UserDetailsService userDetailsService(DataSource dataSource) {
return new JdbcUserDetailsManager(dataSource);
}
Security Filter Chain
@Bean
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests(requests ->
requests
.requestMatchers(HttpMethod.GET, "/restaurant/**", "/menu/**").permitAll()
.requestMatchers(HttpMethod.POST, "/register").permitAll()
.anyRequest().authenticated()
)
.cors(Customizer.withDefaults())
.csrf(csrf -> csrf.disable())
.httpBasic(Customizer.withDefaults())
.build();
}
Authentication Controller
@GetMapping("/login")
public ResponseEntity<?> loginUser() {
return new ResponseEntity<>("Authentication successful", HttpStatus.OK);
}
Authorize users with React
const authorize = () => {
fetch("http://localhost:8080/login", {
headers: { "Authorization": 'Basic ' + window.btoa(email + ":" + password) }
}).then(response => console.log((response.ok === true) ? "successful" : "unsuccessful"));
}
Password encoder, CORS configuration, registration controller, and entities are left out for simplicity.
Problems
- Because
/loginendpoint is only accessible to authenticated user, it should return200if proper authentication details is sent and401otherwise. But I am guessing this does not useSecurityContextHolderto authenticate user if the user was already authenticated beforehand and it is fetching user details from database on each call. How can I ensure the context is being utilized to authenticate users? - Let's say I want to make a call to an authenticated endpoint such as
/order, would I have to addAuthorizationheader on each call? Is there a way to store whether the user is authenticated or not for a certain amount of time? Other threads suggested thatlocalStorageand cookies are unsafe methods.