Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring-Boot REST service basic http auth exclude one endpoint

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?

like image 820
chrisinmtown Avatar asked Jul 28 '17 13:07

chrisinmtown


People also ask

How do you restrict the endpoint of a spring boot?

Use Method-level Authorization To Restrict An Endpoint This tells Spring to check that the authenticated user has the Admin authority, and if not, deny the request. Run the app: ./gradlew bootRun . Navigate to http://localhost:8080/restricted . You'll get a 403 / Unauthorized whitepage error.

What is @API annotation in spring boot?

The @API annotations as per the documentation states “The annotation @Api is used to configure the whole API, and apply to all public methods of a class unless overridden by @APIMethod”. Note the words unless overridden. Often you find that you casually go ahead and mark a class with @API.


2 Answers

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.

like image 179
chrisinmtown Avatar answered Sep 22 '22 12:09

chrisinmtown


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");
    }
like image 31
Ashraf Sarhan Avatar answered Sep 22 '22 12:09

Ashraf Sarhan