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.
Request for Proposal
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
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.