T.Away T.Away - 1 month ago 16
reST (reStructuredText) Question

Spring-Boot adding basic http security to REST service

I am tasked with building a REST service which requires authentication on a couple of actions, while permitting anonymous users on others.

For example:

| Path | Requires authentication |
| /add | YES |
| /{name} | NO |
| /report/{id} | YES |


However I'm having issues with setting up spring-security to work this way.

If I override
WebSecurityConfigurerAdapter
configure
function like this:

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.and()
.httpBasic()
.and()
.authorizeRequests()
//.antMatchers(HttpMethod.GET, "/{name}").permitAll() // I can't really specify a dynamic url here, can i?
.anyRequest().authenticated();
}


With this configuration, any action I invoke will first display the standard browser basic authentication pop-up form. That is what I want, except I don't want this on the dynamic url
/{name}
action.

So instead I tried removing
.anyRequest().authenticated()
and activating
@PreAuthorize
and
@PostAuthorize
annotations with
@EnableGlobalMethodSecurity(proxyTargetClass = true, prePostEnabled = true)

and add annotations to controller actions as following:

| Path | Annotation |
| /add | @PreAuthorize("isAuthenticated()") |
| /{name} | @PreAuthorize("permitAll()") |
| /report/{id} | @PreAuthorize("isAuthenticated()") |


With this the
/{name}
action allows anonymous users as expected, however
/add
and
/report/{id}
actions now just return "Access is denied" with status 500, instead of forcing basic auth.

How can I force basic authentication on select controller methods while allowing anonymous access on others?

Answer

Specifying the configuration for every urls should do the tricks :

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf().disable()                
            .and()
            .httpBasic()
            .and()
            .authorizeRequests()                
            .antMatchers(HttpMethod.GET, "/*").permitAll()
            .antMatchers(HttpMethod.GET, "/add").authenticated()
            .antMatchers(HttpMethod.GET, "/report/*").authenticated()
            .anyRequest().authenticated();                
}