title: How do I set up Spring Security to allow REST calls from specific apps?
body: <p>A Spring Boot app uses Spring Security to protect elements of its API from unauthorized users.  But the app has public url patterns that need to be callable from un-authenticated users, as long as those users are from certain apps.  <strong>What specific changes need to be made to the code below so that the <code>/some-test-service</code> end point can be successfully called from an un-authenticated user from a specific calling location?</strong>  </p>
  
  <p>I will know, for example, that the terminal commands are being run from the same localhost that runs the Spring Boot app.  I will also know that the front end AngularJS/Node.js calling app is running on a specific port, like <code>port 9000</code>.  </p>
  
  <p>Here is what happens when I type in the following <code>POST</code> test from the CentOS terminal in the devbox that runs the Spring Boot app:  </p>
  
  <pre><code>[user@localhost controllers]$ curl -i -X POST -H "Content-Type:application/json" -d '{  "wleadid" : "1" }' http://localhost:8001/some-test-service
  HTTP/1.1 403 Forbidden
  Server: Apache-Coyote/1.1
  X-Content-Type-Options: nosniff
  X-XSS-Protection: 1; mode=block
  Cache-Control: no-cache, no-store, max-age=0, must-revalidate
  Pragma: no-cache
  Expires: 0
  X-Frame-Options: DENY
  Set-Cookie: JSESSIONID=530A75F962CCFB95EEDF43051BC71573; Path=/; HttpOnly
  Content-Type: application/json;charset=UTF-8
  Transfer-Encoding: chunked
  Date: Wed, 06 Apr 2016 09:11:09 GMT
  {"timestamp":1459933869769,"status":403,"error":"Forbidden","message":"Expected CSRF token not found. Has your session expired?","path":"/some-test-service"}  
  [user@localhost controllers]$ 
  </code></pre>
  
  <p>And here is the Spring Security config, in the complete <code>UiApplication.java</code> that that is the main class of the Spring Boot app:  </p>
  
  <pre><code>@SpringBootApplication
  @Controller
  @EnableJpaRepositories(basePackages = "demo", considerNestedRepositories = true)
  public class UiApplication extends WebMvcConfigurerAdapter {
  
      @Autowired
      private Users users;
  
      public static void main(String[] args) {
          SpringApplication.run(UiApplication.class, args);
      }
  
      @Bean
      public PasswordEncoder passwordEncoder() {
          return new BCryptPasswordEncoder();
      }
  
      @Bean
      public LocaleResolver localeResolver() {
          SessionLocaleResolver slr = new SessionLocaleResolver();
          slr.setDefaultLocale(Locale.US);
          return slr;
      }
  
      @Bean
      public LocaleChangeInterceptor localeChangeInterceptor() {
          LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
          lci.setParamName("lang");
          return lci;
      }
  
      @Override
      public void addInterceptors(InterceptorRegistry registry) {
          registry.addInterceptor(localeChangeInterceptor());
      }
  
      @Order(Ordered.HIGHEST_PRECEDENCE)
      @Configuration
      protected static class AuthenticationSecurity extends GlobalAuthenticationConfigurerAdapter {
  
          @Autowired
          private Users users;
  
          @Override
          public void init(AuthenticationManagerBuilder auth) throws Exception {
              auth.userDetailsService(users);
          }
      }
  
      @SuppressWarnings("deprecation")
      @Configuration
      @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
      @EnableWebMvcSecurity
      @EnableGlobalMethodSecurity(prePostEnabled = true)
      protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  
          @Override
          protected void configure(HttpSecurity http) throws Exception {
              http
                  .formLogin()
                      .successHandler(new MyAuthenticationSuccessHandler())
                      .and()
                  .httpBasic().and()
                  .authorizeRequests()
                      .antMatchers("/some-test-service").permitAll()
                      .antMatchers("/", "/url1", "/url2", "/url3*", "/url4*", "/url5*").permitAll()
                      .anyRequest().authenticated()
                      .and()
                  .csrf()
                      .csrfTokenRepository(csrfTokenRepository())
                      .and()
                  .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
          }
  
          private Filter csrfHeaderFilter() {
              return new OncePerRequestFilter() {
                  @Override
                  protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
                          throws ServletException, IOException {
                      System.out.println("----- INSIDE new OncePerRequestFilter().doFilterInternal(...) ");
                      CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
                      if (csrf != null) {
                          Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                          String token = csrf.getToken();
                          if (cookie == null || token != null &amp;&amp; !token.equals(cookie.getValue())) {
                              cookie = new Cookie("XSRF-TOKEN", token);
                              cookie.setPath("/");
                              response.addCookie(cookie);
                          }
                      }
                      filterChain.doFilter(request, response);
                      System.out.println("csrf.getToken() is: "+csrf.getToken());
                  }
              };
          }
  
          private CsrfTokenRepository csrfTokenRepository() {
              HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
              repository.setHeaderName("X-XSRF-TOKEN");
              System.out.println("repository.toString() is: "+repository.toString());
              return repository;
          }
  
      }
  
      @Repository
      interface UserRepository extends CrudRepository&lt;User, Long&gt; {
          User findByName(String name);
      }
  
  }
  </code></pre>