• spring security method security


    参考

    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

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.jiangchong</groupId>
        <artifactId>methodsecurity</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>war</packaging>
    
        <name>methodsecurity</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.3.2.RELEASE</version>
        </parent>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <scope>compile</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-core</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-web</artifactId>
                <scope>compile</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-config</artifactId>
            </dependency>
        </dependencies>
    </project>

    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
    @SpringBootApplication
    public class App
    {
        @Autowired
        public IBookService bookService;
    
        public static void main(String[] args)
        {
            SpringApplication.run(App.class, args);
        }
    
        @RequestMapping("/")
        public Map<String, String> test()
        {
            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<String, String> testAdmin() {
         * Map<String, String> map = new HashMap<>(); map.put("admin", "admin");
         * return map; }
         * 
         * @RequestMapping("/user") public Map<String, String> testUser(String name)
         * { Map<String, String> map = new HashMap<>(); map.put("user", "user");
         * return map; }
         * 
         * @RequestMapping("/resource/test") public Map<String, String>
         * testResouce() { Map<String, String> 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;
    
    @Service
    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", "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
    @EnableWebSecurity
    public 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);
    这些调用序列,只要有一个不满足权限,后面的方法不会再调用
  • 相关阅读:
    DDD(Domain Driven Design) 架构设计
    兴哥:美团下一个十年,要让新一批管理者成长起来
    Java设计模式-Builder构造者模式
    社会需要转型变革,自己更需要转型变革-屡败屡战
    Guava 源码分析之Cache的实现原理
    缓存算法(FIFO 、LRU、LFU三种算法的区别)
    Guava---缓存之LRU算法
    Boost.Asio 网络编程([译]Boost.Asio基本原理)
    浅谈 Boost.Asio 的多线程模型
    boost.asio系列——io_service
  • 原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/5206000.html
Copyright © 2020-2023  润新知