I have the following classes and want to realize role based authentication and but it never permits the request as it probably does not recognize the roles. What can be the possible problem here?
User entity
@Entity
@JsonIgnoreProperties(value = {"createdAt", "updatedAt", "roles", "enabled",
"authorities", "credentialsNonExpired", "accountNonLocked", "accountNonExpired"})
@Data
@Accessors(chain = true)
public class User extends Base implements UserDetails {
@Size(min = 4, max = 20)
@NotNull
private String username;
//@Size(min = 4, max = 20)
@NotNull
private String password;
@NotNull
@Email
private String email;
@ElementCollection(fetch = FetchType.EAGER)
private List<Role> roles = new ArrayList<>();
@OneToMany
private List<Book> bookList = new ArrayList<>();
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return roles.stream().map((Role r) -> new SimpleGrantedAuthority(r.toFullString())).collect(Collectors.toList());
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
Role enum
public enum Role {
ADMIN("ADMIN"),
USER("USER");
private final String text;
Role(final String text) {
this.text = text;
}
@Override
public String toString() {
return text;
}
public String toFullString() {return "ROLE_" + text;}
}
WebSecurityConfig
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
JwtTokenProvider jwtTokenProvider;
@Autowired
UserService userService;
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic().disable()
.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/actuator/**").hasAuthority(Role.ADMIN.toString())
.antMatchers("/").permitAll()
.antMatchers(HttpMethod.DELETE,"/user/remove").hasAnyAuthority(Role.ADMIN.toString(), Role.USER.toString())
.antMatchers(HttpMethod.PUT, "/user/create").permitAll()
.antMatchers(HttpMethod.POST, "/signin").permitAll()
.antMatchers("/admin/**").hasAuthority(Role.ADMIN.toString())
.and()
.apply(new JwtConfig(jwtTokenProvider));
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin")
.password(bCryptPasswordEncoder().encode("abcd123"))
.roles(Role.ADMIN.toString());
auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder());
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return source;
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
And this is how I set the roles of a new user
@Transactional
public GenericResponse create(UserDTO userDTO) {
if (usernameExists(userDTO.getUsername())) {
throw new UsernameExistsException(String.format("Username %s already exists", userDTO.getUsername()));
}
User user = modelMapper.map(userDTO, User.class);
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()))
.setRoles(Arrays.asList(Role.USER, Role.ADMIN))
.setId(UUID.randomUUID().toString());
if (userRepository.save(user) != null) {
return genericResponseService.createResponseNoError(user);
} else throw new RuntimeException();
}
I am sending /user/remove request for a user I created right before. Newly generated users always have USER role as seen above.
Controller
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
UserService userService;
@PutMapping(value = "create", consumes = "application/json")
public GenericResponse create(@Valid @RequestBody UserDTO userDTO) {
return userService.create(userDTO);
}
@DeleteMapping(value = "remove", consumes = "application/json")
public GenericResponse remove(@Valid @RequestBody UserDTO userDTO) {
return userService.remove(userDTO);
}
}