Rumah  >  Artikel  >  Java  >  Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

WBOY
WBOYke hadapan
2023-04-18 19:40:101030semak imbas

    1. Pengenalan kepada Shiro:

    Apache Shiro ialah rangka kerja (kebenaran) keselamatan Java.
    Shiro menjadikannya sangat mudah untuk membangunkan aplikasi yang cukup baik Ia boleh digunakan bukan sahaja dalam persekitaran JavaSE, tetapi juga dalam persekitaran JavaEE. Shiro boleh melakukan semuanya, pengesahan, kebenaran, penyulitan, pengurusan sesi, penyepaduan web, caching dan banyak lagi.

    Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    fungsi shiro:

    Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    Pengesahan: pengesahan identiti, log masuk, sahkan sama ada pengguna mempunyai yang sepadan Identiti;
    Kebenaran: kebenaran, iaitu, pengesahan kebenaran, mengesahkan sama ada pengguna yang disahkan mempunyai kebenaran tertentu, iaitu, menentukan sama ada pengguna boleh melakukan sebarang operasi, seperti: mengesahkan sama ada pengguna mempunyai peranan tertentu, atau berbutir halus Sahkan sama ada pengguna mempunyai kebenaran tertentu pada sumber tertentu!
    Pengurus Sesi: Pengurusan sesi, iaitu, sesi pertama selepas pengguna log masuk dan sebelum keluar, semua maklumatnya ada dalam sesi; session can Ia adalah persekitaran JavaSE biasa, atau ia boleh menjadi persekitaran Web
    Kriptografi: penyulitan untuk melindungi keselamatan data, seperti penyulitan kata laluan dan storan dalam pangkalan data dan bukannya storan teks biasa: Sokongan Web , yang boleh disepadukan dengan mudah ke dalam persekitaran Web;
    Caching: Caching, contohnya, selepas pengguna log masuk, maklumat pengguna, peranan dan kebenarannya tidak perlu disemak setiap kali, yang boleh meningkatkan kecekapan
    Concurrency: Shiro menyokong pengesahan serentak bagi aplikasi berbilang benang, iaitu, Jika anda membuka utas lain dalam satu utas, kebenaran boleh disebarkan secara automatik kepadanya
    Pengujian: Berikan sokongan ujian
    Jalankan Sebagai: Benarkan satu pengguna untuk berpura-pura menjadi pengguna lain (jika mereka membenarkannya) untuk mengakses;
    Ingat Saya: Ingat saya, ini adalah fungsi yang sangat biasa, iaitu, selepas log masuk sekali, anda tidak perlu log masuk lain kali

    Seni bina Shiro (luaran)

    Dari luar Shiro, iaitu, perhatikan cara menggunakan shiro untuk menyiapkan kerja dari perspektif aplikasi:

    Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    subjek: Objek yang berinteraksi secara langsung dengan kod aplikasi ialah Subjek, yang bermaksud teras API luaran Shiro ialah Subjek, Subjek mewakili pengguna semasa ini tidak semestinya orang tertentu aplikasi semasa ialah Subjek, seperti perangkak web, robot, dsb. Semua interaksi dengan Subjek akan diwakilkan kepada SecurityManager sebenarnya adalah Fasad, SecurityManageer ialah pelaksana sebenar
    SecurityManager: Security Manager, iaitu, semua keselamatan-; operasi yang berkaitan akan berinteraksi dengan SecurityManager, dan ia menguruskan semua Subjek Ia dapat dilihat bahawa ia adalah teras Shiro dan bertanggungjawab untuk Berinteraksi dengan komponen Shiro yang lain, yang setara dengan peranan SpringMVC
    DispatcherServlet
    . Realm: Shiro memperoleh data keselamatan (seperti pengguna, peranan, kebenaran) daripada Realm, iaitu, SecurityManager ingin mengesahkan identiti pengguna, maka ia adalah perlu untuk mendapatkan pengguna yang sepadan daripada Realm untuk perbandingan untuk menentukan sama ada identiti pengguna adalah sah; ia juga perlu untuk mendapatkan peranan dan kebenaran pengguna yang sepadan daripada Realm untuk mengesahkan sama ada operasi pengguna boleh dijalankan sebagai Sumber Data

    Seni bina Shiro (dalaman)

    Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    subjek: mana-mana 'pengguna' yang boleh berinteraksi dengan aplikasi itu; dikawal melalui Pengurus Keselamatan, yang menguruskan semua Subjek dan bertanggungjawab untuk pengesahan, kebenaran, sesi dan pengurusan cache

    Pengesah: Bertanggungjawab untuk pengesahan Subjek dan merupakan titik lanjutan, anda boleh menyesuaikan pelaksanaan gunakan strategi pengesahan (AuthenticationStrategy), iaitu, dalam keadaan apakah pengesahan pengguna diluluskan; iaitu, Mengawal fungsi yang boleh diakses oleh pengguna dalam aplikasi

    Realm: Boleh ada satu atau lebih alam, yang boleh dianggap sebagai sumber data entiti selamat, iaitu, digunakan untuk mendapatkan entiti selamat, yang boleh dilaksanakan menggunakan DBC atau memori, dsb., disediakan oleh pengguna, jadi secara amnya dalam aplikasi, anda perlu melaksanakan alam anda sendiri
    SessionManager: komponen yang menguruskan kitaran hayat Sesi, dan Shiro bukan sahaja boleh digunakan dalam Persekitaran web, tetapi juga dalam persekitaran JavaSE biasa
    CacheManager: Pengawal cache untuk menguruskan cache seperti pengguna, peranan, kebenaran, dll. kerana data ini jarang diakses, menambahkannya ke cache boleh meningkatkan prestasi akses
    Kriptografi: modul kriptografi , Shiro telah menambah baik beberapa komponen penyulitan biasa untuk penyulitan kata laluan, penyahsulitan, dsb.

    2. Mula Pantas

    Salin kes

    1 . Ikut gesaan tapak web rasmi untuk mencari alamat Case GitHub mula pantas: shiro/samples/quickstart/

    Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java2. Buat projek Maven baharu, padamkan direktori srcnya dan gunakannya sebagai projek induk

    3 Cipta modul Maven baharu dalam projek induk

    4

    <dependencies>
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-core</artifactId>
                <version>1.4.1</version>
            </dependency>
     
            <!-- configure logging -->
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>jcl-over-slf4j</artifactId>
                <version>1.7.29</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>1.7.29</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
        </dependencies>

    5. Salin log4j.properties di bawah sumber dalam kes permulaan pantas

    6. Salin fail shiro.ini

    7 🎜>

    8. Jalankan Quickstart.java

    Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    2. Analisis kod

    public class Quickstart {
        private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
        public static void main(String[] args) {
            //工厂模式,通过shiro.ini配置文件中的信息,生成一个工厂实例
            Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
            SecurityManager securityManager = factory.getInstance();
            SecurityUtils.setSecurityManager(securityManager);
            //获取当前的用户对象Subject
            Subject currentUser = SecurityUtils.getSubject();
            //通过当前用户拿到session
            Session session = currentUser.getSession();
            session.setAttribute("someKey", "aValue");
            String value = (String) session.getAttribute("someKey");
            if (value.equals("aValue")) {
                log.info("Subject=>session[" + value + "]");
            }
            //判断当前的用户是否被认证
            if (!currentUser.isAuthenticated()) {
                //Token :令牌,没有获取,随机
                UsernamePasswordToken token = new UsernamePasswordToken("lonestarr", "vespa");
                token.setRememberMe(true);  //设置记住我
                try {
                    currentUser.login(token); //执行了登录操作
                } catch (UnknownAccountException uae) {
                    //如果   用户名不存在
                    log.info("There is no user with username of " + token.getPrincipal());
                } catch (IncorrectCredentialsException ice) {
                    //如果   密码不正确
                    log.info("Password for account " + token.getPrincipal() + " was incorrect!");
                } catch (LockedAccountException lae) {
                    //用户被锁定,如密码输出过多,则被锁定
                    log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                            "Please contact your administrator to unlock it.");
                }
                //...在此处捕获更多异常
                catch (AuthenticationException ae) {
                    //意外情况 ? 错误 ?
                }
            }
            //打印其标识主体(在这种情况下,为用户名)
            log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
     
            //测试角色是否存在
            if (currentUser.hasRole("schwartz")) {
                log.info("May the Schwartz be with you!");
            } else {
                log.info("Hello, mere mortal.");
            }
            //粗粒度,极限范围小
            //测试类型化的极限(不是实例级别)
            if (currentUser.isPermitted("lightsaber:wield")) {
                log.info("You may use a lightsaber ring.  Use it wisely.");
            } else {
                log.info("Sorry, lightsaber rings are for schwartz masters only.");
            }
            //细粒度,极限范围广
            //实例级别的权限(非常强大)
            if (currentUser.isPermitted("winnebago:drive:eagle5")) {
                log.info("You are permitted to &#39;drive&#39; the winnebago with license plate (id) &#39;eagle5&#39;.  " +
                        "Here are the keys - have fun!");
            } else {
                log.info("Sorry, you aren&#39;t allowed to drive the &#39;eagle5&#39; winnebago!");
            }
            //注销
            currentUser.logout();
            //退出
            System.exit(0);
        }
    }
    3 >1. Tulis persekitaran ujian

    1 Cipta modul springboot baharu dalam projek induk sebentar tadi

    2 pakej penyepaduan Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    Berikut ialah tiga elemen utama untuk menulis fail konfigurasi

    Shiro
     <!--SpringBoot 和 Shiro 整合包-->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.4.1</version>
            </dependency>


    Pengguna subjek-> ShiroFilterFactoryBean

    SecurityManager menguruskan semua pengguna-> ; DefaultWebSecurityManager
    Data sambungan realm



    Tertib penciptaan objek dalam operasi sebenar: realm -> securityManager -> perlu mewarisi AuthorizingRealm

    4 Cipta fail konfigurasi ShiroConfig baharu

    5.
    //自定义的 UserRealm        extends AuthorizingRealm
    public class UserRealm extends AuthorizingRealm {
        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            //打印一个提示
            System.out.println("执行了授权方法");
            return null;
        }
     
        //认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            //打印一个提示
            System.out.println("执行了认证方法");
            return null;
        }
    }

    @Configuration
    public class ShiroConfig {
     
        //ShiroFilterFactoryBean:3
        @Bean
        public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebsecurityManager){
            ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
            //设置安全管理器
            bean.setSecurityManager(defaultWebsecurityManager);
            return bean;
        }
        //DefaultWebSecurityManager:2
        @Bean(name="securityManager")
        public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
            DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
            //关闭UserRealm
            securityManager.setRealm(userRealm);
            return securityManager;
        }
        //创建realm 对象,需要自定义类:1
        @Bean(name="userRealm")
        public UserRealm userRealm(){
            return new UserRealm();
        }
    }

    2 Gunakan

    1. Pemintasan log masuk Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    Tambah permintaan log masuk yang perlu dipintas dalam kaedah getShiroFilterFactoryBean

    Ujian: Mengklik pautan tambah tidak akan melompat ke halaman tambah, tetapi ke halaman log masuk, dan pemintasan berjaya

    @Configuration
    public class ShiroConfig {
     
        //ShiroFilterFactoryBean:3
        @Bean
        public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebsecurityManager){
            ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
            //设置安全管理器
            bean.setSecurityManager(defaultWebsecurityManager);
            //添加shiro的内置过滤器
            /*
                anon : 无需认证,就可以访问
                authc : 必须认证了才能访问
                user : 必须拥有 “记住我” 功能才能用
                perms : 拥有对某个资源的权限才能访问
                role : 拥有某个角色权限才能访问
             */
     
            filterMap.put("/user/add","authc");
            filterMap.put("/user/update","authc");
            //拦截
            Map<String,String> filterMap=new LinkedHashMap<>();
            filterMap.put("/user/*","authc");
            bean.setFilterChainDefinitionMap(filterMap);
     
    //        //设置登录的请求
    //        bean.setLoginUrl("/toLogin");
            return bean;
        }

    2

    1. Tulis kaedah log masuk dalam lapisan Pengawal Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    2. Ujian

    //登录的方法
        @RequestMapping("/login")
        public String login(String username, String password, Model model) {
            //获取当前用户
            Subject subject = SecurityUtils.getSubject();
            //封装用户的登录数据,获得令牌
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            //登录 及 异常处理
            try {
                //执行用户登录的方法,如果没有异常就说明OK了
                subject.login(token);
                return "index";
            } catch (UnknownAccountException e) {
                //如果用户名不存在
                System.out.println("用户名不存在");
                model.addAttribute("msg", "用户名错误");
                return "login";
            } catch (IncorrectCredentialsException ice) {
                //如果密码错误
                System.out.println("密码错误");
                model.addAttribute("msg", "密码错误");
                return "login";
            }
        }
    }

    Ia boleh dilihat bahawa adat UserRealm dilaksanakan terlebih dahulu kaedah AuthenticationInfo, dan kemudian melakukan operasi berkaitan log masuk

    3 Ubah suai kaedah doGetAuthenticationInfo dalam UserRealm Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    4 >

    //认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            //打印一个提示
            System.out.println("执行了认证方法");
            // 用户名密码
            String name = "root";
            String password = "123456";
            //通过参数获取登录的控制器中生成的 令牌
            UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
            //用户名认证
            if (!token.getUsername().equals(name)){
                // return null UnKnownAccountException
                return null;
            }
            //密码认证, Shiro 自己做,为了避免和密码的接触
            //最后返回一个 AuthenticationInfo 接口的实现类,这里选择 SimpleAuthenticationInfo
            // 三个参数:获取当前用户的认证 ; 密码 ; 认证名
            return new SimpleAuthenticationInfo("", password, "");
        }
    }

    Masukkan kata laluan yang betul untuk berjaya log masuk

    Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java4 Shiro mengintegrasikan Mybatis

    1 >Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    2. Cipta aplikasi baharu.yml

    3 Dalam aplikasi.properties

    4 🎜>5. Tulis Kelas Pengguna
    <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.19</version>
            </dependency>
     
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
     
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.12</version>
            </dependency>
           <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.1</version>
            </dependency>

    6 Tulis UserMapper
    spring:
      datasource:
        username: root
        password: 123456
        url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource
     
        #Spring Boot 默认是不注入这些属性值的,需要自己绑定
        #druid 数据源专有配置
        initialSize: 5
        minIdle: 5
        maxActive: 20
        maxWait: 60000
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: SELECT 1 FROM DUAL
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
     
        #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
        #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
        #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
        filters: stat,wall,log4j
        maxPoolPreparedStatementPerConnectionSize: 20
        useGlobalDataSourceStat: true
        connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
    mybatis:
      type-aliases-package: com.huang.pojo
      mapper-locations: classpath:mybatis/mapper/*.xml

    7 Tulis UserMapper.xml
    mybatis.type-aliases-package=com.longdi.pojo
    mybatis.mapper-locations=classpath:mapper/*.xml

    8 >
    <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.10</version>
                <scope>provided</scope>
            </dependency>
    Antara Muka Perkhidmatan Pengguna:

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
            private int id;
            private String name;
            private String pwd;
            private String perms;
    }
    9 Tulis kelas pelaksanaan antara muka UserServiceImpl

    @Repository
    @Mapper
    public interface UserMapper {
        public User  queryUserByName(String name);
     
    }
    10 Ujian dalam ShiroSpringbootApplicationTests

    1.>
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     
    <mapper namespace="com.longdi.mapper.UserMapper">
     
        <select id="queryUserByName" resultType="User" parameterType="String">
            select * from mybatis.user where name=#{name}
        </select>
     
    </mapper>
    1 sambung ke pangkalan data

    5. Laksanakan kebenaran permintaan

    1 Ubah suai dalam kelas ShiroConfig
    public interface UserService {
        public User queryUserByName(String name);
    }

    @Service
    public class UserServiceImpl implements UserService{
     
        @Autowired
        UserMapper userMapper;
     
        @Override
        public User queryUserByName(String name) {
            return userMapper.queryUserByName(name);
        }
    }

    2

    @SpringBootTest
    class ShiroSpringbootApplicationTests {
        @Autowired
        UserServiceImpl userService;
        @Test
        void contextLoads() {
            System.out.println(userService.queryUserByName("longdi"));
        }
    }

    3 Log masuk untuk memintas kebenaran dan menguji dengan jayanya

    Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    4 kaedah doGetAuthorizationInfo

    Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    5. Minta ujian kebenaran berjaya

    6 Shiro menyepadukan ThymeleafCara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    1

    2. Integrasi ShiroDialectCara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    3.index.htmlCara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    Ujian

    <!--shiro和thymeleaf整合-->
            <dependency>
                <groupId>com.github.theborakompanioni</groupId>
                <artifactId>thymeleaf-extras-shiro</artifactId>
                <version>2.0.0</version>
            </dependency>

    5. Letakkan sesi

    Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    dalam pengesahan 6. Ubah suai index.html

    Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java

    Atas ialah kandungan terperinci Cara menggunakan rangka kerja keselamatan Apache Shiro dalam Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

    Kenyataan:
    Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam