Home  >  Spring Security

@PreAuthorize and @PostAuthorize in Spring Security

By Arvind Rai, December 27, 2013
Spring security provides method level security using @PreAuthorize and @PostAuthorize. This is expression-based access control. @PreAuthorize can check for authorization before entering into method. @PreAuthorize is checked on the basis of role or the argument which is passed to the method. @PostAuthorize checks for authrorisation after method execution. @PostAuthorize can be authorized on the basis of logged in roles, return object by method and passed argument to the method. For the returned object spring security provides built-in keyword i.e. returnObject. Define @PreAuthorize and @PostAuthorize in the interface of the service layer.
IBookService.java
package com.concretepage.service;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import com.concretepage.bean.Book;
public interface IBookService {
	@PreAuthorize ("hasRole('ROLE_WRITE')")
	public void addBook(Book book);

	@PostAuthorize ("returnObject.owner == authentication.name")
	public Book getBook();

	@PreAuthorize ("#book.owner == authentication.name")
	public void deleteBook(Book book);
}
 
Look at the interface how to define @PreAuthorize and @PostAuthorize. authentication and principal keyword can directly be used to access user information. # is used to access argument of the method. Take attention on @PostAuthorize, built-in keyword returnObject has been used. Here returnObject is equivalent to Book instance returned by the method. Now find the spring security XML.
security-config.xml
  <http auto-config="true" use-expressions="true">
   <intercept-url pattern="/login" access="hasAnyRole('ROLE_READ','ROLE_WRITE')" />
   <logout logout-success-url="/login" />
  </http>
  <authentication-manager>
  <authentication-provider>
   <user-service>
	<user name="ram" password="con1234" authorities="ROLE_READ,ROLE_WRITE" />
	<user name="rahim" password="con1234" authorities="ROLE_READ" />
  </user-service>
  </authentication-provider>
  </authentication-manager>
  <global-method-security pre-post-annotations="enabled"/>
  <beans:bean name="bookService" class="com.concretepage.service.BookService"/>
 
Enable pre-post annotations using global-method-security namespace as given below
<global-method-security pre-post-annotations="enabled"/>
 
In case we are using java configuration, then that class needs to be annotated with @EnableGlobalMethodSecurity such as
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

}
Now for the example I have taken two role ROLE_READ and ROLE_WRITE and two user ram and rahim. ram is authorized with both roles whereas rahim is authorized with ROLE_READ. Find configuration to run the example.
BookService.java
package com.concretepage.service;
import com.concretepage.bean.Book;
public class BookService implements IBookService {
	@Override
	public void addBook(Book book) {
		System.out.println("You have successfully added book.");		
	}
	@Override
	public Book getBook() {
		Book book = new Book("B", "ram");
		return book;
	}
	@Override
	public void deleteBook(Book book) {
	  System.out.println("Books deleted");		
	}
}
 
Book.java
package com.concretepage.bean;
public class Book {
	private String name;
	private String owner;
	public Book(String name,String owner){
		this.name = name;
		this.owner = owner;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getOwner() {
		return owner;
	}
	public void setOwner(String owner) {
		this.owner = owner;
	}
}
 
LoginController.java
package com.concretepage.security.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.concretepage.bean.Book;
import com.concretepage.service.IBookService;
@Controller
@RequestMapping("/login")
public class LoginController {
	@Autowired
	public IBookService bookService;
	@RequestMapping(method = RequestMethod.GET)
	public String success(ModelMap map) {		
		Book b1 = new Book("A","rahim");
		bookService.addBook(b1);
		bookService.getBook();
		Book b2 = new Book("B","ram");
		bookService.deleteBook(b2);
		map.addAttribute("msg", "Done Successfully");
		return "success";
	}  
}
 
Download the source code from the end of the blog and use URL as http://localhost:8080/SpringSecurity/login You will get the below UI
@PreAuthorize and @PostAuthorize in Spring Security
Try with both user. When we try with ram, we will get success message because in the IBooKService and LoginController, there is scenario for ram to be accessible.
@PreAuthorize and @PostAuthorize in Spring Security
Try with rahim user, we will get access HTTP Status 403 - Access is denied message.
@PreAuthorize and @PostAuthorize in Spring Security
Download Complete Source Code
POSTED BY
ARVIND RAI
ARVIND RAI
FIND MORE TUTORILAS
comments powered by Disqus








Copyright ©2017 concretepage.com, all rights reserved |Privacy Policy | Contact Us