shiro

Shrio

Shrio快速入门

Subject用户
SecurityManager 管理所有用户
Realm 连接数据

  1. 导入依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <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">
        <parent>
            <artifactId>spring-08-shiro</artifactId>
            <groupId>com.wen</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>hello-shiro</artifactId>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
        <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>
                <scope>runtime</scope>
                <version>1.7.21</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <scope>runtime</scope>
                <version>1.7.21</version>
            </dependency>
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <scope>runtime</scope>
                <version>1.2.17</version>
            </dependency>
        </dependencies>
    </project>
    
  2. 编写配置文件

    
    [users]
    root = secret, admin
    guest = guest, guest
    presidentskroob = 12345, president
    darkhelmet = ludicrousspeed, darklord, schwartz
    lonestarr = vespa, goodguy, schwartz
    
    
    [roles]
    # 'admin' role has all permissions, indicated by the wildcard '*'
    admin = *
    # The 'schwartz' role can do anything (*) with any lightsaber:
    schwartz = lightsaber:*
    # The 'goodguy' role is allowed to 'drive' (action) the winnebago (type) with
    # license plate 'eagle5' (instance specific id)
    goodguy = winnebago:drive:eagle5
    
  3. 测试

    /*
     * Licensed to the Apache Software Foundation (ASF) under one
     * or more contributor license agreements.  See the NOTICE file
     * distributed with this work for additional information
     * regarding copyright ownership.  The ASF licenses this file
     * to you under the Apache License, Version 2.0 (the
     * "License"); you may not use this file except in compliance
     * with the License.  You may obtain a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing,
     * software distributed under the License is distributed on an
     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     * KIND, either express or implied.  See the License for the
     * specific language governing permissions and limitations
     * under the License.
     */
    
    import org.apache.shiro.SecurityUtils;
    import org.apache.shiro.authc.*;
    import org.apache.shiro.config.IniSecurityManagerFactory;
    
    import org.apache.shiro.mgt.SecurityManager;
    import org.apache.shiro.session.Session;
    import org.apache.shiro.subject.Subject;
    
    import org.apache.shiro.util.Factory;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    
    /**
     * Simple Quickstart application showing how to use Shiro's API.
     *
     * @since 0.9 RC2
     */
    public class Quickstart {
    
        private static final transient Logger log = LoggerFactory.getLogger(Quickstart.class);
    
    
        public static void main(String[] args) {
    
            // The easiest way to create a Shiro SecurityManager with configured
            // realms, users, roles and permissions is to use the simple INI config.
            // We'll do that by using a factory that can ingest a .ini file and
            // return a SecurityManager instance:
    
            // Use the shiro.ini file at the root of the classpath
            // (file: and url: prefixes load from files and urls respectively):
            Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
            SecurityManager securityManager = factory.getInstance();
    
            // for this simple example quickstart, make the SecurityManager
            // accessible as a JVM singleton.  Most applications wouldn't do this
            // and instead rely on their container configuration or web.xml for
            // webapps.  That is outside the scope of this simple quickstart, so
            // we'll just do the bare minimum so you can continue to get a feel
            // for things.
            SecurityUtils.setSecurityManager(securityManager);
    
            // Now that a simple Shiro environment is set up, let's see what you can do:
    
            // get the currently executing user:
            //获取当前的用户的对象Subject
            Subject currentUser = SecurityUtils.getSubject();
    
            // Do some stuff with a Session (no need for a web or EJB container!!!)
            //通过当前用户拿到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 more exceptions here (maybe custom ones specific to your application?
                catch (AuthenticationException ae) {
                    //unexpected condition?  error?
                }
            }
    
            //say who they are:
            //print their identifying principal (in this case, a username):
            log.info("User [" + currentUser.getPrincipal() + "] logged in successfully.");
    
            //test a role:
            if (currentUser.hasRole("schwartz")) {
                log.info("May the Schwartz be with you!");
            } else {
                log.info("Hello, mere mortal.");
            }
    
            //test a typed permission (not instance-level)
            //粗粒度
            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.");
            }
    
            //a (very powerful) Instance Level permission:
            //细粒度
            if (currentUser.isPermitted("winnebago:drive:eagle5")) {
                log.info("You are permitted to 'drive' the winnebago with license plate (id) 'eagle5'.  " +
                        "Here are the keys - have fun!");
            } else {
                log.info("Sorry, you aren't allowed to drive the 'eagle5' winnebago!");
            }
    
            //all done - log out!
            //注销
            currentUser.logout();
            //结束
            System.exit(0);
        }
    }
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210323210300230.png)
    
    
    
    
  4. 关键方法

//获取当前的用户的对象Subject
Subject currentUser = SecurityUtils.getSubject();
//通过当前用户拿到Session
Session session = currentUser.getSession();
//判断当前的用户是否被认证
currentUser.isAuthenticated()
//获得用户认证
currentUser.getPrincipal()
//获得用户角色
currentUser.hasRole
粗粒度
currentUser.isPermitted("lightsaber:wield")
//注销
currentUser.logout();

Shiro里有的 Spring Security里都有只是名字发生了改变

SpringBoot集成Shiro

编写测试环境

  1. 导入依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.4.4</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.wen</groupId>
        <artifactId>shiro-springboot</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>shiro-springboot</name>
        <description>Demo project for Spring Boot</description>
        <properties>
            <java.version>1.8</java.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--thymeleaf-->
            <dependency>
                <groupId>org.thymeleaf</groupId>
                <artifactId>thymeleaf-spring5</artifactId>
            </dependency>
            <dependency>
                <groupId>org.thymeleaf.extras</groupId>
                <artifactId>thymeleaf-extras-java8time</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
  2. 编写index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>首页</h1>
    </body>
    </html>
    
  3. 编写Controller

    package com.wen.shirospringboot.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class MyController {
        @RequestMapping({"/","/index"})
        public String toIndex(Model model){
            model.addAttribute("msg","测试环境搭建");
            return "index";
    
        }
    }
    
  4. 测试环境是否搭建成功

在这里插入图片描述

前端正常显示参数,环境搭建成功

整合Shiro

  1. 导入依赖

    <!--shiro整合spring的包-->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.4.1</version>
    </dependency>
    
  2. 编写自定义UserRealm

    package com.wen.shirospringboot.config;
    
    import org.apache.shiro.authc.AuthenticationException;
    import org.apache.shiro.authc.AuthenticationInfo;
    import org.apache.shiro.authc.AuthenticationToken;
    import org.apache.shiro.authz.AuthorizationInfo;
    import org.apache.shiro.realm.AuthorizingRealm;
    import org.apache.shiro.subject.PrincipalCollection;
    
    /**
     * @author 20212
     * 自定义的 UserRealm
     */
    public class UserRealm extends AuthorizingRealm {
        //授权
        @Override
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            System.out.println("执行了=>授权doGetAuthorizationInfo");
            return null;
        }
    
        //认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            System.out.println("执行了=>认证doGetAuthorizationInfo");
            return null;
        }
    }
    
  3. 编写ShiroConfig

    package com.wen.shirospringboot.config;
    
    import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
    import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class ShiroConfig {
        //ShiroFilterFactoryBean
        public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager){
            ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
            //设置安全管理器
            bean.setSecurityManager(defaultWebSecurityManager);
            return bean;
        }
        //DefaultWebSecurityManager
        @Bean("securityManager")
        public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm) {
            DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
            securityManager.setRealm(userRealm);
            return securityManager;
        }
    
        //创建 realm 对象,需要自定义类1
        @Bean
        public UserRealm userRealm() {
            return new UserRealm();
        }
    }
    
  4. 编辑前端测试页面user/add.htmluser/update.html
    add页面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>add</h1>
    </body>
    </html>
    

    update页面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>update</h1>
    </body>
    </html>
    
  5. MyController类下增加这两个方法用来跳转视图

    @RequestMapping("/user/add")
    public String add(){
        return "user/add";
    }
    @RequestMapping("/user/update")
    public String update(){
        return "user/update";
    }
    
  6. 测试能否正常访问user/adduser/update

在这里插入图片描述

在这里插入图片描述

Shiro实现登录拦截

Shrio里实现登录拦截功能是使用过滤器来完成的

  • 添加Shiro内置的过滤器

    • anon:无需认证就可以访问
    • authc:必须认证了才能访问
    • user:必须拥有 记住我 功能才可以访问
    • perms:拥有某个资源的权限才能访问
    • role:拥有某个角色权限才能访问
  1. 编写login.html

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>首页</h1>
    <p th:text="${msg}"></p>
    <hr>
    <a th:href="@{/user/add}">add</a>|<a th:href="@{/user/update}">update</a>
    </body>
    </html>
    
  2. MyController类下增加toLogin方法

    @RequestMapping("/toLogin")
    public String toLogin(){
        return "login";
    }
    
  3. shiroConfig类下的getShiroFilterFactoryBean方法里设置如下

    //添加shiro的内置过滤器
    /*
       anon:无需认证就能访问
       authc:必须认证了才能访问
       user:必须拥有 记住我 功能才能访问
       perms:拥有对某个资源的权限才能访问
       role:拥有某个角色权限才能访问
     */
    Map<String, String> map = new LinkedHashMap<>();
    map.put("/user/*", "authc");
    bean.setFilterChainDefinitionMap(map);
    //设置登录页面
    bean.setLoginUrl("toLogin");
    return bean;
    
  4. 测试能否成功拦截

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QRJi6mGJ-1616504477010)(C:\Users\20212\AppData\Roaming\Typora\typora-user-images\image-20210322214721050.png)]

访问/user/add成功拦截并通过toLoginConttiroller成功跳转到login.html页面

Shiro实现拦截成功

Shiro实现用户认证

  1. myController类中编辑login方法

    @RequestMapping("/login")
    public String login(String username, String password, Model model) {
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        //封装用户的登录数据
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
    
        try {
            subject.login(token);
            return "index";
        } catch (UnknownAccountException e) {//用户名不存在
            model.addAttribute("msg", "用户名不存在");
            return "login";
        } catch (IncorrectCredentialsException e) {
            model.addAttribute("msg", "密码错误");
            return "login";
        }
    }
    
  2. 在认证方法里编写

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了=>认证doGetAuthorizationInfo");
        //伪造用户名,密码;
        String name="root";
        String password="123456";
        UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
          if(!userToken.getUsername().equals(name)){
              //自动抛出异常 UnknownAccountException
              return null;
          }
    
        //密码认证,shiro帮我们做
        return new SimpleAuthenticationInfo("",password,"");
    }
    
  3. login.html里显示用户登录失败信息,和表单请求跳转地址

    <form action="/login">
       <p th:text="${msg}" style="color: red"></p>
        <p><input type="text" name="username">用户名</p>
        <p><input type="password" name="password">密码</p>
        <input type="submit" value="登录">
    </form>
    
  4. 测试

    密码错误正常显示

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ngeF7gVv-1616504477011)(C:\Users\20212\AppData\Roaming\Typora\typora-user-images\image-20210323133959202.png)]

用户名不存在正常显示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nZtJPG8s-1616504477012)(C:\Users\20212\AppData\Roaming\Typora\typora-user-images\image-20210323134025148.png)]

用户名和密码都正确正常登录到首页

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yZ7nyq5m-1616504477013)(C:\Users\20212\AppData\Roaming\Typora\typora-user-images\image-20210323134105020.png)]

Shiro整合Mybatis

  1. 创建数据库

    CREATE TABLE `user`  (
      `id` int(11) NOT NULL,
      `name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
      `pwd` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
      `perms` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    
    INSERT INTO `user` VALUES (1, 'wen', '123', 'user:add');
    INSERT INTO `user` VALUES (3, '李四', '123456', NULL);
    INSERT INTO `user` VALUES (6, '李五', '12356', NULL);
    INSERT INTO `user` VALUES (7, 'root', '123456', 'user:update');
    
    
  2. 导入依赖

    <!--lombok-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.18</version>
    </dependency>
    <!--Druid-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.1</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.4</version>
    </dependency>
    
  3. 编写application.yaml文件

    spring:
      datasource:
        username: xxxx
        password:  xxxx
        url: jdbc:mysql://cdb-1tjyxzq8.cd.tencentcdb.com:10198/mybatis?useUnicode=true&characterEncoding=utf-8
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource
        #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.Properity
        #则导入log4j 依赖就行
        filters: stat,wall,log4j
        maxPoolPreparedStatementPerConnectionSize: 20
        useGlobalDataSourceStat: true
        connectionoProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
    mybatis:
      type-aliases-package: com.wen.pojo
      mapper-locations: classpath:mapper/*.xml
    
  4. 编写UserMapper接口和对应的mapper文件

    @Mapper
    @Repository
    public interface UserMapper {
    
        User queryUserByName(String name);
    }
    
    <?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.wen.shirospringboot.mapper.UserMapper">
    
        <select id="queryUserByName" resultType="com.wen.shirospringboot.pojo.User">
            select * from user where name =#{name}
        </select>
    </mapper>
    
  5. 编写service接口和对应的实现

    public interface UserService {
        User queryUserByName(String name);
    }
    
    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserMapper userMapper;
    
        @Override
        public User queryUserByName(String name) {
            return userMapper.queryUserByName(name);
        }
    }
    
  6. 编写测试类 测试是否连接数据库成功

    @SpringBootTest
    class ShiroSpringbootApplicationTests {
    @Autowired
    private UserService userService;
        @Test
        void contextLoads() {
            System.out.println(userService.queryUserByName("李四"));
        }
    
    }
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OTnZHaME-1616504477013)(C:\Users\20212\AppData\Roaming\Typora\typora-user-images\image-20210323141343974.png)]

    正常返回结果连接数据库成功

  7. 把之前我么仿造的数据换成数据库里真是存在的数据

    @Autowired
    private UserService userService;
     //认证
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            System.out.println("执行了=>认证doGetAuthorizationInfo");
            //伪造用户名,密码;
            UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
            User user = userService.queryUserByName(userToken.getUsername());
            System.out.println("=>"+userToken.getUsername());
           if (user==null){//没有这人
               return null;
           }
    
            //密码认证,shiro帮我们做
            return new SimpleAuthenticationInfo("",user.getPwd(),"");
        }
    
  8. 测试

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P3xVjJXL-1616504477013)(C:\Users\20212\AppData\Roaming\Typora\typora-user-images\image-20210323145119409.png)]

    能实现登录访问正常访问

Shiro请求授权实现

  1. 通过SimpleAuthenticationInfo传递当前用户的信息

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("执行了=>认证doGetAuthorizationInfo");
        //伪造用户名,密码;
        UsernamePasswordToken userToken = (UsernamePasswordToken) authenticationToken;
        User user = userService.queryUserByName(userToken.getUsername());
        System.out.println("=>"+userToken.getUsername());
       if (user==null){//没有这人
           return null;
       }
    
        //密码认证,shiro帮我们做
        return new SimpleAuthenticationInfo(user,user.getPwd(),"");
    }
    
  2. 添加授权信息

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了=>授权doGetAuthorizationInfo");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //拿到当前的登录对象
        Subject subject = SecurityUtils.getSubject();
        User principal = (User) subject.getPrincipal();
        info.addStringPermission(principal.getPerms());
        return info;
    }
    
  3. 添加权限访问

    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManager") DefaultWebSecurityManager defaultWebSecurityManager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        //添加shiro的内置过滤器
        /*
           anon:无需认证就能访问
           authc:必须认证了才能访问
           user:必须拥有 记住我 功能才能访问
           perms:拥有对某个资源的权限才能访问
           role:拥有某个角色权限才能访问
         */
        Map<String, String> filterMap = new LinkedHashMap<>();
        filterMap.put("/user/add","perms[user:add]");
        filterMap.put("/user/update","perms[user:update]");
    
        bean.setFilterChainDefinitionMap(filterMap);
        //设置登录页面
        bean.setLoginUrl("/toLogin");
        //设置没有权限
        bean.setUnauthorizedUrl("/noauth");
        return bean;
    }
    
  4. 测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8CykAgfK-1616504477014)(C:\Users\20212\AppData\Roaming\Typora\typora-user-images\image-20210323155115282.png)]

请求授权实现成功

Shiro整合Thymeleaf

现在我们的主页面是这个样子的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4ZcrdXt4-1616504477014)(file://C:\Users\20212\AppData\Roaming\Typora\typora-user-images\image-20210323145119409.png?lastModify=1616488436)]

导 入依赖

  1. 导入依赖

    <!--shiro整合thymeleaf的包-->
    <dependency>
        <groupId>com.github.theborakompanioni</groupId>
        <artifactId>thymeleaf-extras-shiro</artifactId>
        <version>2.0.0</version>
    </dependency>
    
  2. 在主页中进行设

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org"
    xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>首页</h1>
    <div shiro:guest="true">
        <a th:href="@{/toLogin}">登录</a>
    </div>
    <div shiro:hasPermission="user:add">
    <p th:text="${msg}"></p>
    </div>
    
    <hr>
    <div shiro:hasPermission="user:add">
        <a th:href="@{/user/add}">add</a>|</div>
    <div shiro:hasPermission="user:update">
    <a th:href="@{/user/update}">update</a>
    </div>
    </body>
    </html>
    
  3. 配置一个ben用来整合 shiro thymeleaf

    //整合ShiroDialect:用来真个和 shiro thymeleaf
        @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
    

    之后我们在登陆就能根据角色拥有的权限来显示页面了

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qRgBRKVe-1616504477015)(C:\Users\20212\AppData\Roaming\Typora\typora-user-images\image-20210323163640743.png)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值