6

I have a REST-only micro service built on Spring-Boot version 1.5.4.RELEASE with spring-boot-starter-security. The service has no web pages, just JSON in and out. The username and password are configured in the application.properties file. With credit to http://ryanjbaxter.com/2015/01/06/securing-rest-apis-with-spring-boot/ the following configuration causes the server to implement basic HTTP authentication quite nicely, it accepts the credentials and rejects unauthorized requests:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().authorizeRequests() //
                .anyRequest().authenticated().and().httpBasic();        
    }
}

My question is that I'd like to exclude one little ole path, one tiny endpoint, from basic HTTP authentication. From frantic googling and SO copy-pasting I revised the above to have this:

    http.csrf().disable().authorizeRequests() //
        .antMatchers("/healthcheck").permitAll()
        .anyRequest().authenticated().and().httpBasic();

This compiles and runs without warning, but that path is not opened for unauthenticated access. I still must supply credentials to check the service health.

Do I have to match paths one by one? My little healthcheck endpoint is at the base of the context path, as are a whole bunch of others - adding paths one-by-one would be a hassle.

The relevant part of my application.properties file is:

security.user.name = web-user
security.user.password = web-pass
management.security.roles=SUPERUSER

Maybe I need to fiddle roles somehow?

Please help, thanks in advance.

Update 1:

Path information - I'd like this path (and many more at root) to be guarded:

localhost:8081/abcd/user

And I'd like ONLY this one path to be open, no auth required:

localhost:8081/abcd/healthcheck

Update 2: Looks like I largely duplicated this 3-year-old question, but no answer was accepted there for my issue:

spring-boot setup basic auth on a single web app path?

chrisinmtown
  • 3,571
  • 3
  • 34
  • 43

3 Answers3

5

Well after more experimenting I found that the following works - @efekctive please note that there is no context prefix on the healthcheck:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().authorizeRequests()
     .antMatchers("/healthcheck").permitAll()
     .antMatchers("/**").authenticated().and().httpBasic();
}

One big caveat: when I posted this I was testing the healthcheck endpoint by invoking curl with BOGUS http credentials, expecting Spring to ignore them, but Spring always answered 401-unauthorized. The proper test is to invoke curl with NO http credentials at all, then the healthcheck endpoint answers quite happily.

chrisinmtown
  • 3,571
  • 3
  • 34
  • 43
  • Tried this, doesn't work for me. Just fyi, i am using sessionCreationPolicy instead of httpBasic – Adi Aug 07 '19 at 19:26
2

I have added the following to the SecurityConfig in my Springboot service and it works fine, I was able to exclude some endpoint from the basic auth.

@Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/customers/**/hints", "/customers/**/search", "/customers/**/clientConfig");
    }
Ashraf Sarhan
  • 1,507
  • 16
  • 21
  • This code snippet does not show a call to method authorizeRequests(). In your service do any endpoints require authorization? – chrisinmtown Aug 31 '20 at 20:08
  • I do configure basic auth on all the endpoints and swagger by the following code @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http.httpBasic() // it indicate basic authentication is required .and() .authorizeRequests() .antMatchers("/swagger-ui.html**").permitAll() .antMatchers("/**").authenticated(); } – Ashraf Sarhan Sep 03 '20 at 15:17
0

You say your link looks like:

localhost:8081/abcd/healthcheck

Try this:

http.csrf().disable().authorizeRequests() //
    .antMatchers("/abcd/healthcheck").permitAll()
    .anyRequest().authenticated().and().httpBasic();
JavaBoy
  • 182
  • 7
  • Thank you @JavaBoy for the very fast reply but no joy yet.. I used that code, tested by requesting that endpoint with curl without supplying any credentials; the response is 401 unauthorized. – chrisinmtown Jul 28 '17 at 13:52
  • Have you tried with @EnableWebSecurity on your class? https://github.com/spring-projects/spring-boot/issues/8646 – JavaBoy Jul 28 '17 at 14:02
  • I see the same behavior whether @EnableWebSecurity annotation is present or absent on the WebSecurityConfigurerAdapter class. – chrisinmtown Jul 28 '17 at 14:20
  • Check the bottom of this page: https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-monitoring.html#production-ready-health-access-restrictions – JavaBoy Jul 29 '17 at 16:14