1
votes

I'm learning Spring Security. I have my login system ready and I want to add roles. I've seen many tutorials and docs about it and I couldn't find what I'm looking for.

I don't want to create an extra table for Roles, because my table user has a column named "type" and I want to use it for authorization. The value of that column can be "person", "teacher" or "organization". So, I want to based the role system on that column, not in a OneToMany o ManyToMany relationship with a table named "role".

How can I configure that?

Thanks

UPDATED

I forgot, I'm using Spring Data. This is the code I'm using

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    private AuthenticationProvider authenticationProvider;

    @Autowired
    @Qualifier("daoAuthenticationProvider")
    public void setAuthenticationProvider(AuthenticationProvider authenticationProvider) {
        this.authenticationProvider = authenticationProvider;
    }

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

    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider(BCryptPasswordEncoder passwordEncoder,
                                                               UserDetailsService userDetailsService){

        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
        daoAuthenticationProvider.setUserDetailsService(userDetailsService);
        return daoAuthenticationProvider;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.csrf().ignoringAntMatchers("/h2-console").disable()
                .authorizeRequests().antMatchers("/").authenticated()
                .antMatchers("/console/**").permitAll()
                .antMatchers("/static/**").permitAll()
                .antMatchers("/profile").hasAuthority("PERSON")
                .and().formLogin().loginPage("/login").permitAll()
                .and().exceptionHandling().accessDeniedPage("/login")
                .and().logout().permitAll()

        http.headers().frameOptions().disable();
    }


    @Autowired
    public void configureAuthManager(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception{
        authenticationManagerBuilder
                .jdbcAuthentication().authoritiesByUsernameQuery("select type from users where username = ?").and()
                .authenticationProvider(authenticationProvider);
    }




}
1
Where is your authenticationProvider? Add that too.. - Ali Dehghani
Ok, I added the entire configuration, you can see the provider as "daoAuthenticationProvider" - Giuliano

1 Answers

1
votes

You can define a UserDetailsService with a PasswordEncoder in Java Config like following:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired private PersonRepository personRepository;

    @Override
    @Autowired
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .userDetailsService(username -> {
                    Person person = personRepository.findByUsername(username);
                    if (person == null) throw new UsernameNotFoundException("Invalid user");

                    return new User(person.getUsername(),
                            person.getPassword(),
                            Collections.singleton(new SimpleGrantedAuthority(person.getType())));
                })
                .passwordEncoder(passwordEncoder())
    }

    // Rest of the configuration
}

In the above example, i supposed you have a PersonRespository that has access to your user information. With this UserDetailsService you won't need your AuthenticationProvider. Also, User resides in org.springframework.security.core.userdetails package.