libnull-dev libnull-dev - 11 months ago 74
Java Question

Sending credentials in secured spring-boot application using fetch API

I was following this tutorial with the only difference that I used Fetch API for querying REST repository. My problem is that after successful authorization every

call returns response containing login form html string. Specifically, this kind of code

fetch(`${root}/employees?size=${pageSize}`).then( p => p.json()})

produces the following error in Chrome console:

localhost/:1 Uncaught (in promise) SyntaxError: Unexpected token < in
JSON at position 0

If I add a header with authorization to

fetch(`${root}/employees?size=${pageSize}`, {
method: 'GET',
headers: new Headers({'Content-Type': 'application/json',
'Authorization': 'Basic '+btoa('greg:turnquist'))})

all works, but this looks silly after all effort put in configuring
Spring Security
and for sure it is not the best practice.

All java sources remain the same as in tutorial but I include fragments from configuration classes here:

@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

private SpringDataJpaUserDetailsService userDetailsService;

protected void configure(AuthenticationManagerBuilder auth) throws Exception {

protected void configure(HttpSecurity http) throws Exception {
.antMatchers("/build/**", "/main.css").permitAll()
.defaultSuccessUrl("/", true)


public class SpringDataJpaUserDetailsService implements UserDetailsService {

private final ManagerRepository repository;

public SpringDataJpaUserDetailsService(ManagerRepository repository) {
this.repository = repository;

public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {
Manager manager = this.repository.findByName(name);
return new User(manager.getName(), manager.getPassword(),


public interface EmployeeRepository extends PagingAndSortingRepository<Employee, Long> {

@PreAuthorize("#employee?.manager == null or #employee?.manager?.name == authentication?.name")
Employee save(@Param("employee") Employee employee);

@PreAuthorize("@employeeRepository.findOne(#id)?.manager?.name == authentication?.name")
void delete(@Param("id") Long id);

@PreAuthorize("#employee?.manager?.name == authentication?.name")
void delete(@Param("employee") Employee employee);


So my question is how to send credential from authorized page using new
fetch API to interact with REST repositories without additional security configuration?

Answer Source

The root of the problem is that fetch() doesn't send cookies by default. So I should add credentials: 'include' to request options object:

fetch(`${root}/employees?size=${pageSize}`, {
  method: 'GET',
  credentials: 'include'})