【问题标题】:Only allow frontend to make calls to backend api?只允许前端调用后端 api?
【发布时间】:2018-02-17 04:22:46
【问题描述】:

我有一个带有 spring-boot 的应用程序。我为“api/...”调用添加了一些控制器,这些控制器可以执行 angular-frontend 需要的不同操作。如何保护这些 url,以便只有我的前端可以访问 examplelpe.com/api/... 而不是每个用户?我不希望任何人能够从他们的浏览器访问examlpe.com/api/...,但他们应该能够访问example.com。

url example.com/api/userinfo 发回有关当前登录用户的信息。只有我的前端才能进行这些调用。

我意识到需要为这些调用实施某种身份验证。调用 api 时是否发送某种令牌。最佳做法是什么?

【问题讨论】:

标签: java rest google-app-engine spring-boot spring-security


【解决方案1】:

这似乎可以通过 spring 安全认证来实现。在发送请求时,您需要传递身份验证参数,这些参数将由 spring-security 模块验证,然后调用将到达您的控制器。我还没试过。

检查一下: How to secure REST API with Spring Boot and Spring Security?

【讨论】:

    【解决方案2】:

    创建两个包或至少两个类文件来提供服务,比如说

    1. FrontController.java 只提供 html 文件
    2. FrontApi.java 仅提供 api 数据

    添加基于 Spring 令牌(jwt)的安全性,这样没有令牌,任何人都无法从浏览器访问您的 api。 Angular 非常支持为每个请求添加令牌。

    @Controller
    @RequestMapping("/")
    public class FrontController {
    
        @RequestMapping(value = "", method = RequestMethod.GET)
        public String getFrontPage(){
            return "/frontPage";
        }
    }
    
    
    @RestController
    @RequestMapping("/api/v1/front")
    public class FrontApi {
    
        @RequestMapping(value = "", method = RequestMethod.GET)
        public Data getFrontData(){
            // call service
            // return data
        }
    }
    
    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .antMatchers("/").permitAll()
                    .anyRequest().authenticated()
                    .and()
                .formLogin()
                    .loginPage("/login")
                    .permitAll()
                    .and()
                .logout()
                    .permitAll();
        }
    }
    

    别忘了添加安全依赖,我跳过前端代码。

    <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-security</artifactId>
     </dependency>
    

    【讨论】:

      【解决方案3】:

      您可以通过将 Access-Control-Allow-Origin 字段中允许的 URL 添加到标头来添加自定义 CORSFilter 和重新字符串请求的来源。下面是如何实现这一点 -

      public class CORSFilter implements Filter {
      
      public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
          System.out.println("Filtering on...........................................................");
          HttpServletResponse response = (HttpServletResponse) res;
          response.setHeader("Access-Control-Allow-Origin", "permitted URL here");
          response.setHeader("Access-Control-Allow-Credentials", "true");
          response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
          response.setHeader("Access-Control-Max-Age", "3600");
          response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Authorization, Origin, Accept, Access-Control-Request-Method, Access-Control-Request-Headers");
      
          chain.doFilter(req, res);
      }
      
      public void init(FilterConfig filterConfig) {}
      
      public void destroy() {}
      
      }
      

      您可以根据需要修改此过滤器。

      编辑

      上述方法并不完全安全,因为入侵者可能会破坏标头值。最好的解决方案是使用基于令牌的身份验证。 JWT 是这里的最佳选择之一。

      【讨论】:

      • 因为我们可以使用邮递员并将我们自定义的已知标头添加到此。我认为这不会有帮助。
      猜你喜欢
      • 1970-01-01
      • 2020-02-13
      • 2022-11-20
      • 2019-02-15
      • 2021-12-31
      • 2017-01-09
      • 2011-11-11
      • 2016-11-05
      • 2016-01-16
      相关资源
      最近更新 更多