// Step 1: Define a custom enum for roles (if not already defined)
public enum CustomRole {
ROLE_USER,
ROLE_ADMIN,
// Add other roles as needed
}
// Step 2: Create a UserDetailsServiceImpl implementing UserDetailsService
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// Implement logic to load user details from your data source (e.g., database)
// Include user roles in the returned UserDetails object
// Use authorities to represent roles (e.g., new SimpleGrantedAuthority("ROLE_USER"))
}
}
// Step 3: Configure authentication and authorization in SecurityConfig class
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/").hasRole(CustomRole.ROLE_ADMIN.name())
.antMatchers("/user/").hasRole(CustomRole.ROLE_USER.name())
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
// Step 4: Update the User entity to include roles
@Entity
public class User {
// ... existing fields ...
@ElementCollection(targetClass = CustomRole.class, fetch = FetchType.EAGER)
@CollectionTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id"))
@Enumerated(EnumType.STRING)
private Set<CustomRole> roles;
// ... getters and setters ...
}
// Step 5: Update the UserRepository to find users by username
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
}