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页面,登录失败

每个人都会有一段异常艰难的时光 。 生活的压力 , 工作的失意 , 学业的压力。 爱的惶惶不可终日。 挺过来的 ,人生就会豁然开朗。 挺不过来的 ,时间也会教你 ,怎么与它们握手言和 ,所以不必害怕的。 ——杨绛
原文地址:https://www.cnblogs.com/zhai1997/p/13710842.html