Search code examples
restspring-bootweb-servicesspring-securitybasic-authentication

Spring Security for web service without roles and authorities


I have a REST web service built on Spring Boot. For authentication I use Spring Security and Basic Authentication and I am new to this. Do I have to use Roles and Authorities for my solution?

I only want the user of the web service to state user name and password credentials. I don't have any users in a database or elsewhere.

In my WebSecurityConfigurerAdapter configuration I now have .authorities("ROLE_USER"); in the end of my configureGlobal method, following examples on the internet. I would like to skip that so that the class would look like this:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

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

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

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

I found I can not do that. I works if I use .roles("USER") instead. But I do not want to handle neither authorities nor roles, just a user name and a password. Why do I need this or how can I skip this?

I am greatful for any light you can shed on this matter (authentication and Spring Security) to a novice.


Solution

  • If you use inMemoryAuthentication you normally provide the roles via roles("...")

    InMemoryAuthentication does not work with null as GrantedAuthorities. So not calling roles(...) causes an BeanCreationException

    But nothing prevents you from providing an empty list... like:

    @Configuration
    class SecurityConfig extends WebSecurityConfigurerAdapter {
    
        public void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.inMemoryAuthentication()
                    .withUser("username")
                    .password(passwordEncoder().encode("password"))
                    .roles(); // <--- leave roles empty
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable()
                    .authorizeRequests()
                    .anyRequest().authenticated().and().httpBasic();
        }
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }
    

    Note: Don't think you need @EnableWebSecurity or use configureGlobal ...


    Or you can always choose to create your own custom AuthenticationProvider.

    Configuration of a custom AuthenticationProvider:

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth.authenticationProvider(authProvider());
        }
    
        @Bean
        public AuthenticationProvider authProvider() {
            return new CustomAuthenticationProvider();
        }