Home > Mobile >  Fetch response is 401 Unauthenticated React Frontend Spring Boot Backend with Spring Security
Fetch response is 401 Unauthenticated React Frontend Spring Boot Backend with Spring Security

Time:01-27

I have created this Spring Boot backend for a university assignment, which requires authorization/authentication. I have made the api work fine standalone , and the calls go through with correct authorization/authentication through Postman requests. But when i try to call the api from a react app, it always returns unauthanticaded 401.

I removed the security completely from the api, just to see if it would work, it does , the api calls return the results as expected (without Spring Security). But when i re-add Spring security only the Postman requests work.

Javascript Fetch requests don't work (Returning 401)

var myHeaders = new Headers();
myHeaders.append("Authorization", "Basic "   btoa("root:root"));

const res = await fetch("http://localhost:7979/api/users", myHeaders)
console.log(res);
const data = await res.json();
console.log(data);

Console Output: enter image description here

and wget/curl requests don't work with both outputing Connection Refused enter image description here

Successful Postman request: enter image description here

Here is the security config from the spring boot backend:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfig
{
    
    @Resource
    private DataSource dataSource;
    
    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception
    {
        http.authorizeHttpRequests(auth -> auth
                               .requestMatchers(HttpMethod.POST , "/api/users").permitAll()
                                .requestMatchers( "/api/authority").hasAuthority(Constants.ADMIN)
                               .anyRequest().authenticated()
                )
                .formLogin().permitAll()
                .and().logout().permitAll()
                .and().userDetailsService(userDetailsService)
                .cors()
                .and().csrf().disable()
                .httpBasic();
        
        http.headers().frameOptions().sameOrigin();
        
        
        return http.build();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder()
    {
        return new BCryptPasswordEncoder();
    }
}

the spring backend is run on localhost:7979 and the react app is run on localhost:3000 also, maybe important, i am on windows and run the React app on Windows Subsystem for Linux but the spring app but the default runner of Intellij.

I'm quite stumped and i can't figure out how to debug Spring Security, everyone just says enable logging which i have done but the Spring Security Logging offers 0 useful info (unless i don't understand what I'm seeing)

Update:

So wsl is a bit of a problem, i have this script on .zshrc on wsl that get the ip of the windows host (i don't know how it works, a person here told me to add it and it worked)

script:

export winhost=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }')
if [ ! -n "$(grep -P "[[:space:]]winhost" /etc/hosts)" ]; then
        printf "%s\t%s\n" "$winhost" "winhost" | sudo tee -a "/etc/hosts"
fi

so now if i use the winhost instead of localhost wget/curl works fine

Successful wget request: enter image description here

Successful curl request: enter image description here

I tried doing the same on the React app but it came up with a new error enter image description here

I also tried running the React app on windows instead of wsl , but i had the same result: enter image description here

Update Update:

I found a way to activate logging on spring security, here are the log for a successful request:

2023-01-26T02:00:33.435 02:00 DEBUG 17932 --- [nio-7979-exec-9] o.s.security.web.FilterChainProxy        : Securing GET /api/users
Hibernate: 
    select
        u1_0.`id`,
        u1_0.`AFM`,
        u1_0.`address`,
        u1_0.`email`,
        u1_0.`enabled`,
        u1_0.`password`,
        u1_0.`phone_number`,
        u1_0.`username` 
    from
        `users` u1_0 
    where
        u1_0.`username`=?
Hibernate: 
    select
        a1_0.`user_id`,
        a1_1.`id`,
        a1_1.`authority` 
    from
        `user_authorities` a1_0 
    join
        `authorities` a1_1 
            on a1_1.`id`=a1_0.`authority_id` 
    where
        a1_0.`user_id`=?
Hibernate: 
    select
        u1_0.`authority_id`,
        u1_1.`id`,
        u1_1.`AFM`,
        u1_1.`address`,
        u1_1.`email`,
        u1_1.`enabled`,
        u1_1.`password`,
        u1_1.`phone_number`,
        u1_1.`username` 
    from
        `user_authorities` u1_0 
    join
        `users` u1_1 
            on u1_1.`id`=u1_0.`user_id` 
    where
        u1_0.`authority_id`=?
2023-01-26T02:00:33.508 02:00 DEBUG 17932 --- [nio-7979-exec-9] o.s.s.a.dao.DaoAuthenticationProvider    : Authenticated user
2023-01-26T02:00:33.508 02:00 DEBUG 17932 --- [nio-7979-exec-9] o.s.s.w.a.www.BasicAuthenticationFilter  : Set SecurityContextHolder to UsernamePasswordAuthenticationToken [Principal=gr.hua.dit.it22023_it22026.models.SecurityUserDetails@2e536336, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=172.20.196.70, SessionId=null], Granted Authorities=[ADMIN]]
2023-01-26T02:00:33.509 02:00 DEBUG 17932 --- [nio-7979-exec-9] o.s.security.web.FilterChainProxy        : Secured GET /api/users
Hibernate: 
    select
        u1_0.`id`,
        u1_0.`AFM`,
        u1_0.`address`,
        u1_0.`email`,
        u1_0.`enabled`,
        u1_0.`password`,
        u1_0.`phone_number`,
        u1_0.`username` 
    from
        `users` u1_0
Hibernate: 
    select
        a1_0.`user_id`,
        a1_1.`id`,
        a1_1.`authority` 
    from
        `user_authorities` a1_0 
    join
        `authorities` a1_1 
            on a1_1.`id`=a1_0.`authority_id` 
    where
        a1_0.`user_id`=?
Hibernate: 
    select
        u1_0.`authority_id`,
        u1_1.`id`,
        u1_1.`AFM`,
        u1_1.`address`,
        u1_1.`email`,
        u1_1.`enabled`,
        u1_1.`password`,
        u1_1.`phone_number`,
        u1_1.`username` 
    from
        `user_authorities` u1_0 
    join
        `users` u1_1 
            on u1_1.`id`=u1_0.`user_id` 
    where
        u1_0.`authority_id`=?
Hibernate: 
    select
        a1_0.`user_id`,
        a1_1.`id`,
        a1_1.`authority` 
    from
        `user_authorities` a1_0 
    join
        `authorities` a1_1 
            on a1_1.`id`=a1_0.`authority_id` 
    where
        a1_0.`user_id`=?
Hibernate: 
    select
        a1_0.`user_id`,
        a1_1.`id`,
        a1_1.`authority` 
    from
        `user_authorities` a1_0 
    join
        `authorities` a1_1 
            on a1_1.`id`=a1_0.`authority_id` 
    where
        a1_0.`user_id`=?
Hibernate: 
    select
        u1_0.`authority_id`,
        u1_1.`id`,
        u1_1.`AFM`,
        u1_1.`address`,
        u1_1.`email`,
        u1_1.`enabled`,
        u1_1.`password`,
        u1_1.`phone_number`,
        u1_1.`username` 
    from
        `user_authorities` u1_0 
    join
        `users` u1_1 
            on u1_1.`id`=u1_0.`user_id` 
    where
        u1_0.`authority_id`=?

And here are the logs for a failed request:

2023-01-26T02:02:23.041 02:00 DEBUG 17932 --- [nio-7979-exec-1] o.s.security.web.FilterChainProxy        : Securing GET /api/users
2023-01-26T02:02:23.042 02:00 DEBUG 17932 --- [nio-7979-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2023-01-26T02:02:23.042 02:00 DEBUG 17932 --- [nio-7979-exec-1] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]
2023-01-26T02:02:23.042 02:00 DEBUG 17932 --- [nio-7979-exec-1] s.w.a.DelegatingAuthenticationEntryPoint : No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint@456e1a23
2023-01-26T02:02:23.042 02:00 DEBUG 17932 --- [nio-7979-exec-1] o.s.security.web.FilterChainProxy        : Securing GET /error
2023-01-26T02:02:23.042 02:00 DEBUG 17932 --- [nio-7979-exec-1] o.s.s.w.a.AnonymousAuthenticationFilter  : Set SecurityContextHolder to anonymous SecurityContext
2023-01-26T02:02:23.042 02:00 DEBUG 17932 --- [nio-7979-exec-1] s.w.a.DelegatingAuthenticationEntryPoint : Trying to match using RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]
2023-01-26T02:02:23.042 02:00 DEBUG 17932 --- [nio-7979-exec-1] s.w.a.DelegatingAuthenticationEntryPoint : No match found. Using default entry point org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint@456e1a23

I don't understand the fail request logs at all, can any spring boot security expert help?

CodePudding user response:

issue was in javascript

const res = await fetch("http://localhost:7979/api/users", headers);

should have been

const res = await fetch("http://localhost:7979/api/users", {headers:headers})

  • Related