参考
Spring Security 官方文档
http://www.concretepage.com/spring/spring-security/preauthorize-postauthorize-in-spring-security
方法调用安全
对应的注解@EnableGlobalMethodSecurity,该注解放在GlobalMethodSecurityConfiguration的子类上方
@EnableGlobalMethodSecurity(prePostEnabled = true)
使用的Voter
org.springframework.security.access.prepost.PreInvocationAuthorizationAdviceVoter
有俩对对应的注解
@PreAuthorize 决定方法是否可以被调用
@PostAuthorize 决定方法是否可以返回该值
@PreFilter
@PostFilter
如下:
package com.jiangchong.methodsecurity;import org.springframework.security.access.method.P;import org.springframework.security.access.prepost.PostAuthorize;import org.springframework.security.access.prepost.PreAuthorize;public interface IBookService{ @PreAuthorize("hasRole('ROLE_ADMIN')") public void addBook(Book book); // PostAuthorize,决定这个值是否可以被返回,使用returnObject /* * Less commonly, you may wish to perform an access-control check after the * method has been invoked. This can be achieved using the @PostAuthorize * annotation. To access the return value from a method, use the built-in * name returnObject in the expression. */ @PostAuthorize("returnObject.owner == authentication.name") public Book getBook(); // PreAuthorize,决定这个方法是否可以被调用 /* * @P单个参数的方法 */ @PreAuthorize("#b.owner == authentication.name") public void deleteBook(@P("b") Book book); /* * @Param放在至少有一个参数的方法的上 * * @PreAuthorize("#n == authentication.name") Contact * findContactByName(@Param("n") String name) */ // springEL /* * @PreAuthorize("#contact.name == authentication.name") public void * doSomething(Contact contact); */}
测试的Demo,基于Spring Boot
Pom.xml
4.0.0 com.jiangchong methodsecurity 0.0.1-SNAPSHOT war methodsecurity http://maven.apache.org UTF-8 org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE org.springframework.boot spring-boot-starter-web compile org.springframework.boot spring-boot-starter org.springframework.security spring-security-core org.springframework.security spring-security-web compile org.springframework.security spring-security-config
App.class
package com.jiangchong.methodsecurity;import java.util.Map;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;/** * */@RestController@SpringBootApplicationpublic class App{ @Autowired public IBookService bookService; public static void main(String[] args) { SpringApplication.run(App.class, args); } @RequestMapping("/") public Maptest() { Book b1 = new Book("A", "admin"); bookService.addBook(b1); bookService.getBook(); System.out.println("user return"); Book b2 = new Book("B", "user"); bookService.deleteBook(b2); return null; } /* * @RequestMapping("/admin") public Map testAdmin() { * Map map = new HashMap<>(); map.put("admin", "admin"); * return map; } * * @RequestMapping("/user") public Map testUser(String name) * { Map map = new HashMap<>(); map.put("user", "user"); * return map; } * * @RequestMapping("/resource/test") public Map * testResouce() { Map map = new HashMap<>(); * map.put("test", "resource"); return map; } */}
Book.class
package com.jiangchong.methodsecurity;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; }}
BookService.class
package com.jiangchong.methodsecurity;import org.springframework.stereotype.Service;@Servicepublic 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", "user"); System.out.println("return " + book.getOwner()); return book; } @Override public void deleteBook(Book book) { System.out.println("Books deleted"); }}
IBookService
package com.jiangchong.methodsecurity;import org.springframework.security.access.method.P;import org.springframework.security.access.prepost.PostAuthorize;import org.springframework.security.access.prepost.PreAuthorize;public interface IBookService{ @PreAuthorize("hasRole('ROLE_ADMIN')") public void addBook(Book book); // PostAuthorize,决定这个值是否可以被返回,使用returnObject /* * Less commonly, you may wish to perform an access-control check after the * method has been invoked. This can be achieved using the @PostAuthorize * annotation. To access the return value from a method, use the built-in * name returnObject in the expression. */ @PostAuthorize("returnObject.owner == authentication.name") public Book getBook(); // PreAuthorize,决定这个方法是否可以被调用 /* * @P单个参数的方法 */ @PreAuthorize("#b.owner == authentication.name") public void deleteBook(@P("b") Book book); /* * @Param放在至少有一个参数的方法的上 * * @PreAuthorize("#n == authentication.name") Contact * findContactByName(@Param("n") String name) */ // springEL /* * @PreAuthorize("#contact.name == authentication.name") public void * doSomething(Contact contact); */}
MethodSecurityConfig
package com.jiangchong.methodsecurity;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;@Configuration@EnableGlobalMethodSecurity(prePostEnabled = true)public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration{ protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication(); }}
WebSecurityConfig
package com.jiangchong.methodsecurity;import org.springframework.context.annotation.Configuration;import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;import org.springframework.security.config.annotation.web.builders.HttpSecurity;import org.springframework.security.config.annotation.web.builders.WebSecurity;import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter{ protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().authenticated().and().formLogin() .loginProcessingUrl("/login").permitAll(); } public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/resource/**"); } protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("admin").password("admin") .roles("ADMIN").and().withUser("user").password("user") .roles("USER"); }}
Book b1 = new Book("A", "admin"); bookService.addBook(b1); bookService.getBook(); System.out.println("user return"); Book b2 = new Book("B", "user"); bookService.deleteBook(b2); 这些调用序列,只要有一个不满足权限,后面的方法不会再调用
posted on 2016-02-22 01:35 阅读( ...) 评论( ...)