Role Based Authentication With PreAuthorize In Spring Security

Posted By : Kuldeep Kumar | 29-May-2018
Hey Friends, am going to discuss Role-based authentication with @PreAuthorize in spring security.
 
@PreAuthorize provides expression-based access control to controller methods. since spring security 3.0 @PreAuthorize comes into play.to use @PreAuthorize you have to use "UserDetails" interface provided by spring security this interface contains the number of methods one of them is 
getAuthorities() which returns a collection of "GrantedAuthority".
 

public class CustomUserDetails implements UserDetails{

private User user; //Here User is a simple POJO class

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return user.getRoles().stream().map(role -> new SimpleGrantedAuthority("ROLE_" + role.getRole()))
.collect(Collectors.toList());
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
 
 

@RestController
@RequestMapping("/secure/data")
public class adminController {
@Autowired
private UserRepository userRepository;
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;

@RequestMapping(value = "/one" , method = RequestMethod.GET)
public String getData(@RequestParam("name") String name){

System.out.println("name : "+name);
return "Hi Admin "+name;
}

@PreAuthorize("hasRole('ADMIN')")
@RequestMapping(value = "/add" , method = RequestMethod.POST)
public String addUser(@RequestBody User user){
String pass = user.getPassword();
user.setPassword(bCryptPasswordEncoder.encode(pass));
userRepository.save(user);
return "user added";
}
}
 
 

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter{

@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(encodedPass());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
http.authorizeRequests().antMatchers("/rest/**").authenticated().anyRequest().permitAll().and()
.authorizeRequests().antMatchers("/secure/**").authenticated().anyRequest().hasAnyRole("ADMIN")
.and().formLogin().permitAll();
}
@Bean
public BCryptPasswordEncoder encodedPass(){
return new BCryptPasswordEncoder();
}

}
 
Here antMatchers provides url based security so that person with the particular role can only make the request to that url.as you can see that any URL consisting /secure must only be served to a person with role "ADMIN" while url consisting /rest can be requested by any person.
 
if a user directly makes the request to URL "http://localhost:8080/secure/data/add" then it will be redirected to login page, if a person would have role as "ADMIN" then it will be served by this method otherwise it will be Access Denied with error code 403.
 
you can use @PreAuthorize("hasAuthority('ADMIN')") rather than @PreAuthorize("hasRole('ROLE_ADMIN')") a role is nothing but a special ROLE_ along with authority.
 
 
 
 
 
 
 
 
 

About Author

Author Image
Kuldeep Kumar

Kuldeep is interested in developing web applications and he is currently working on Groovy on Grails. He likes to learn new technologies and love playing chess.

Request for Proposal

Name is required

Comment is required

Sending message..