0
votes

I am using Spring security for a Spring Boot application containing a set of Restful services. I have enabled Web security with basic authentication. I would like to have basic authentication enabled except for specific API URL ending with a certain pattern. (For example, a healthcheck API like: /application/_healthcheck)

Code looks like below:

@Configuration
@EnableWebSecurity
public class ApplicationWebSecurityConfigurer extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationEntryPoint authEntryPoint;

    @Value("${application.security.authentication.username}")
    private String username;

    @Value("${application.security.authentication.password}")
    private String password;

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

    @Autowired
    public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser(username).password(password).roles("USER");
    }

    @Override
    public void configure(final WebSecurity web) throws Exception {
        web.ignoring().antMatchers("*/_healthcheck");
    }
}

However, whenever I invoke the .../application/_healthcheck URL, browser always prompts me to enter credentials.

Alternately, I even tried ignoring this path from Spring boot's application.properties (removed the configure method with web.ignoring().antMatchers("*/_healthcheck")) but still can't get rid of authentication for this endpoint

security.ignored=/_healthcheck,*/_healthcheck
3
Thanks @dur but I added the property configuration only after web.ignoring().antMatchers("*/_healthcheck") didn't work. Removing that configure method and keeping only property configuration also didn't help. - Akash
web.ignoring().antMatchers("*/_healthcheck") is wrong, because of stackoverflow.com/a/43711163/5277820. - dur
Thanks dur, that solved my problem. - Akash

3 Answers

0
votes

You can create a permission list and use it to disable security.

List<String> permitAllEndpointList = Arrays.asList(
            AUTHENTICATION_URL,
            REFRESH_TOKEN_URL,
            EXTERNAL_AUTH_URL,
            "/swagger-resources",
            "/swagger-resources/**",
            "/swagger-ui.html"
);

and then add this statement to your HttpSecurity object

.and()
.authorizeRequests()
.antMatchers(permitAllEndpointList.toArray(new String[permitAllEndpointList.size()]))
.permitAll()

This will solve your issue.

0
votes
@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().antMatchers("/application/_healthcheck");
}

The difference in above sample and your code is usage of web over http. Try with web and see if it work { practically it should :) }.

-1
votes

Try this. This will skip authentication part for health URL.

@Override
protected void configure(final HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("*/_healthcheck").permitAll() // added this line
                .anyRequest().authenticated()
                .and().httpBasic()
                .authenticationEntryPoint(authEntryPoint);
}