2

I am creating a spring boot API and react front end in a project I am working on. There is no user logon on the front end, however, I would like to ensure my API endpoints are secure and only accessed by my react front end and I am struggling to come up with solutions.

One possible solution I was thinking is to secure the API with JWT. Create a user table and create a user for the front end client. When the user visits the front end get a token and validate this token on all requests. I’m not sure if this is a valid approach or if there is another solution better fitted.

The app will be hosted on Heroku, stack: spring boot, react and MySQL database. Anyone come across this before or any advice greatly appreciated.

Andrzej Sydor
  • 1,373
  • 4
  • 13
  • 28
GaB
  • 157
  • 1
  • 3
  • 12
  • hi, interesting, you could use `HttpRequest.isRequestedSessionIdValid()` or `HttpRequest.getSession(false) != null`. – IronMan Dec 10 '20 at 23:38
  • 1
    What are you trying to achieve here? Since you don't require a login the data/actions by provided by the api are accessible by the public anyway? – Bastian Stein Dec 12 '20 at 11:57
  • I am creating an e-commerce site, where the user can checkout as a guest, where I will be working with product ID's on the client which i guessed would need to be secure and only known to verified clients. I am using Stripe for payments so no card information will be passed between API and client. – GaB Dec 12 '20 at 12:07
  • What damage can a malicious user do with the product ids? – Bastian Stein Dec 12 '20 at 12:19
  • Very good question, they wont be able to do anything with it as there are no endpoints for this. The more I think about it I feel I may be over complicating this. So it would be OK to have public API endpoints that don't expose any sensitive data? – GaB Dec 12 '20 at 12:23
  • If you, others in your organisation, or the law, can not think of a reason for it to be secret, I would say it's safe for it to be public. – Bastian Stein Dec 12 '20 at 12:27
  • If the data is useful, and you have many consumers, you might incur costs though because you'll need a better server to serve more traffic. So that could be a reason why you would want to limit access. This you could achieve with some form of rate limiting though. – Bastian Stein Dec 12 '20 at 12:29
  • There is an approach called "threat modelling" which deals with identifying relevant threats and appropriately securing against them. This might be of interest to you. – Bastian Stein Dec 12 '20 at 12:32
  • Yes I plan to use rate limiting and I will check out the threat modelling model. Thanks for your help! – GaB Dec 12 '20 at 12:41

2 Answers2

2

This is not possible.

At its core, this would require the frontend to have access to some secret value with which to authenticate it's request with, i.e. a token. You would then allow requests based on the presence of this secret value, and serve the responses.

However, frontends serve public assets and thus can't have secrets. At the end of the day, any user would be able to inspect their network requests, and extract the token from the requests your frontend makes.

With this information they can then forge their own requests.

Bastian Stein
  • 2,147
  • 1
  • 13
  • 28
0

I would recommend to add domain at allowedOrigins of CORS config :

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.util.Arrays;
import java.util.List;

@Component
public class CorsFilterConfig {

    public static final List<String> allowedOrigins = Arrays.asList("yourDomainsHere");

    @Bean
    public FilterRegistrationBean<CorsFilter> initCorsFilter() {
        // @formatter:off
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.setAllowedHeaders(Arrays.asList("Authorization", "Cache-Control", "Content-Type"));
        config.addAllowedMethod("*");
        config.setAllowedOrigins(allowedOrigins);
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
        // @formatter:on
    }
} 

More

DV Singh
  • 1,038
  • 11
  • 16