• Springboot:springboot整合Shiro(JdbcRealm 方式)


    1、导入依赖

     <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-thymeleaf</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!-- MyBatis -->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.0</version>
            </dependency>
            <!-- mysql驱动 依赖 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.25</version>
                <scope>runtime</scope>
            </dependency>
            <!--Druid-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>1.1.10</version>
            </dependency>
            <!--shiro-->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring</artifactId>
                <version>1.4.1</version>
            </dependency>
        </dependencies>

    2、书写配置文件

    spring:
      datasource:
        druid:
          username: root
          password: root
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://localhost:3306/shiro?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
          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

    3、配置过滤器

    @Configuration
    public class ShiroConfig {
        @Bean
        public JdbcRealm getJdbcRealm(DataSource dataSource){
            //JdbcRealm会自行从数据库查询用户以及权限数据(数据库的表结构要符合JdbcRealm的规范)
            JdbcRealm jdbcRealm=new JdbcRealm();
            jdbcRealm.setDataSource(dataSource);
            //JdbcRealm默认开启认证功能,需要手动开启授权功能
            jdbcRealm.setPermissionsLookupEnabled(true);
            return jdbcRealm;
        }
    
        @Bean
        public DefaultWebSecurityManager getDefaultWebSecurityManager(JdbcRealm jdbcRealm){
            DefaultWebSecurityManager defaultSecurityManager=new DefaultWebSecurityManager();
            defaultSecurityManager.setRealm(jdbcRealm);//SecurityManager完成校验需要realm
            return defaultSecurityManager;
        }
    
        @Bean
        public ShiroFilterFactoryBean  shiroFilterFactoryBean(DefaultSecurityManager securityManager){
            ShiroFilterFactoryBean filter=new ShiroFilterFactoryBean();
            //过滤器是shiro执行权限的核心,进行认证和授权是需要SecurityManager的
            filter.setSecurityManager(securityManager);
            //设置shiro的拦截规则
            Map<String,String> filterMap=new HashMap<>();
            //user:使用remberme的用户可访问
            //perms:对应权限可访问
            //role:对应的角色才能访问
            filterMap.put("/","anon");//anon表示不拦截(匿名用户可访问)
            filterMap.put("/login.html","anon");
            filterMap.put("/regist.html","anon");
            filterMap.put("/user/login","anon");
            filterMap.put("/user/regist","anon");
            filterMap.put("/static/**","anon");
            filterMap.put("/**","authc");//authc表示认证用户可访问
            filter.setFilterChainDefinitionMap(filterMap);
            filter.setLoginUrl("/login.html");
            //设置未授权访问的页面
            filter.setUnauthorizedUrl("/login.html");
            return filter;
        }
    }

    使用数据库中的用户数据的时候,这里的realm是不同的,下面的安全管理器和过滤器是一样的

    4、页面跳转的controller

    @Controller
    public class PageController {
        @RequestMapping("/login.html")
        public String login(){
            return "login";
        }
    
        @RequestMapping("/")
        public String login1(){
            return "login";
        }
    
        @RequestMapping("/index.html")
        public String index(){
            return "index";
        }
    }

    5、认证

    在service层书写方法,根据用户输入的用户名和密码完成用户身份的校验:

    @Service
    public class UserService {
        public void checkLogin(String username,String password) throws Exception{
            Subject subject= SecurityUtils.getSubject();
            UsernamePasswordToken token=new UsernamePasswordToken(username,password);
            subject.login(token);
        }
    }

    书写controller调用service层的校验方法,根据校验的结果跳转到不同的页面并给出相应的提示信息:

    @Controller
    @RequestMapping("user")
    public class UserController {
        @Autowired
        private UserService userService;
        @RequestMapping("login")
        public String login(String username,String password){
            try{
                userService.checkLogin(username,password);
                System.out.println("成功");
                System.out.println(username+password);
                return "index";
            }catch (Exception e){
                e.printStackTrace();
                System.out.println("失败");
                System.out.println(username+password);
                return "login";
            }
        }
    }

    登录页面:

    <body>
        <form action="/user/login">
            <input type="text" name="username">
            <input type="password" name="password">
            <input type="submit" value="提交">
        </form>
    </body>

    index页面:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>index</title>
    </head>
    <body>
       <h3>index</h3>
    </body>
    </html>

    6、数据库

    创建一个名称为users的表,里面有username和password字段:

     这里要注意表的名称,必须为users,否则会给出出错信息:

    必须为users的原因是我们并没有书写操作数据库的代码,默认找的是users表中的数据,因此,名称数固定的

    7、 测试

    (1)输入数据库中存在的用户信息

    (2)输入数据库中不存在的用户信息

     跳转到的是登录页面,未能跳转index页面,登录失败

    每个人都会有一段异常艰难的时光 。 生活的压力 , 工作的失意 , 学业的压力。 爱的惶惶不可终日。 挺过来的 ,人生就会豁然开朗。 挺不过来的 ,时间也会教你 ,怎么与它们握手言和 ,所以不必害怕的。 ——杨绛
  • 相关阅读:
    Mondriaan's Dream POJ
    H
    Superdoku Kattis
    Corn Fields POJ
    旅行的意义 Gym
    G
    J
    Welcome Party ZOJ
    redis入门到精通系列(三):key的通用操作和redis内部db的通用操作
    redis入门到精通系列(二):redis操作的两个实践案例
  • 原文地址:https://www.cnblogs.com/zhai1997/p/13710842.html
Copyright © 2020-2023  润新知