2021-11-23最适合入门的Shiro框架教程(二)(springboot整合Shiro,JdbcRealm表规范,IniRealm,Shiro常用标签,权限菜单实现)

一、SpringBoot应用整合Shiro

1.1创建SpringBoot应用

1.2整合Druid和Mybatis

导入依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.0</version>
</dependency>

配置

spring:
  datasource:
    druid:
      url: jdbc:mysql://localhost:3306/fmmall
      driver-class-name: com.mysql.jdbc.Driver
      username: root
      password: root
      initial-size: 1
      min-idle: 1
      max-active: 20
  web:
    resources:
      static-locations: classpath:/templates/
mybatis:
  type-aliases-package: com.qfedu.shiro2.beans
  mapper-locations: classpath:mappers/*Mapper.xml

1.3整合Shiro 

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.1</version>
</dependency>

ShiroFilter

  1. 拦截用户请求
  2. 根据配置的拦截规则进行控制
import org.apache.shiro.realm.Realm;
import org.apache.shiro.realm.text.IniRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    @Bean
    public IniRealm getIniRealm(){
        IniRealm iniRealm=new IniRealm("classpath:shiro.ini");
        return iniRealm;
    }
    //SecurityManager要完成验证,需要realm
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManage(IniRealm iniRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(iniRealm);
        return securityManager;
    }
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager){
    ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
    filter.setSecurityManager(securityManager);
    //设置拦截规则
        // anon匿名用户可访问
        //authc 认证用户可以访问
        //user 认证用户可以访问
        //perms 对应权限可以访问
        //role 对应的角色可以访问

        Map<String,String> filterMap=new HashMap<>();
        filterMap.put("/","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");
        filter.setFilterChainDefinitionMap(filterMap);
        filter.setLoginUrl("/login.html");
        filter.setUnauthorizedUrl("/login.html");

        return filter;
}
}

resources/shiro.ini
[users]
zhangsan=123456,seller
lisi=666666,ckmgr
admin=222222,admin

[roles]
admin=*
seller=order-add,order-del,order-list
ckmgr=ck-add,ck-del,ck-list

  1. 导入Shiro依赖
  2. 配置Shiro过滤器,拦截需要进行认证和授权的用户
  3. Spring容器配置SecurityManager
  4. 配置Realm!!!SecurityManager需要Realm
  5. Realm???可以Shiro提供,也可以自己定义

认证测试

UserServiceImpl.java

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl {
    public void cheakLogin(String userName,String userPwd) throws Exception{
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(userName,userPwd);
        subject.login(token);
    }
}

UserController.java

import com.qfedu.shiro2.service.UserServiceImpl;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;

@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserServiceImpl userService;
    @RequestMapping("/login")
    public String login(String userName,String userPwd){

        try {
            userService.cheakLogin(userName,userPwd);
            System.out.println("成功!");
            return "index";
        }catch (Exception e){
            System.out.println("登录失败!");
        }
        return "login";
    }
}

templates/login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
login
<hr/>
<form action="/user/login">
    <p>账号:<input type="text" name="userName"/> </p>
    <p>密码:<input type="text" name="userPwd"/> </p>
    <p><input type="submit" value="登录"/> </p>
</form>
</body>
</html>

二、SpringBoot应用整合Shiro——案例(JdbcRealm)

2.1如果使用JdbcRealm,则必须提供JdbcRealm所需的表结构(权限设计)

2.2JdbcRealm规定的表结构

用户信息表 users
角色信息表 user_roles

权限信息表:roles_permissions


- 用户信息表: users

  ```sql
  create table users(
      id int primary key auto_increment,
      username varchar(60) not null unique,
      password varchar(20) not null,
      password_salt varchar(20)
  );
  
  insert into users(username,password) values('zhangsan','123456');
  insert into users(username,password) values('lisi','123456');
  insert into users(username,password) values('wangwu','123456');
  insert into users(username,password) values('zhaoliu','123456');
  insert into users(username,password) values('chenqi','123456');
  ```

- 角色信息表: user_roles

  ```sql
  create table user_roles(
  	id int primary key auto_increment,
      username varchar(60) not null,
      role_name varchar(100) not null
  );
  
  -- admin系统管理员
  -- cmanager 库管人员
  -- xmanager 销售人员
  -- kmanager 客服人员
  -- zmanager 行政人员 
  insert into user_roles(username,role_name) values('zhangsan','admin');
  insert into user_roles(username,role_name) values('lisi','cmanager');
  insert into user_roles(username,role_name) values('wangwu','xmanager');
  insert into user_roles(username,role_name) values('zhaoliu','kmanager');
  insert into user_roles(username,role_name) values('chenqi','zmanager');
  
  ```

- 权限信息表:roles_permissions

  ```sql
  create table roles_permissions(
  	id int primary key auto_increment,
      role_name varchar(100) not null,
      permission varchar(100) not null
  );
  
  -- 权限  sys:c:save   sys:c:delete...
  -- 管理员具备所有权限
  insert into roles_permissions(role_name,permission) values("admin","*");
  -- 库管人员
  insert into roles_permissions(role_name,permission) values("cmanager","sys:c:save");		
  insert into roles_permissions(role_name,permission) values("cmanager","sys:c:delete");
  insert into roles_permissions(role_name,permission) values("cmanager","sys:c:update");
  insert into roles_permissions(role_name,permission) values("cmanager","sys:c:find");
  -- 销售人员
  insert into roles_permissions(role_name,permission) values("xmanager","sys:c:find");
  insert into roles_permissions(role_name,permission) values("xmanager","sys:x:save");
  insert into roles_permissions(role_name,permission) values("xmanager","sys:x:delete");
  insert into roles_permissions(role_name,permission) values("xmanager","sys:x:update");
  insert into roles_permissions(role_name,permission) values("xmanager","sys:x:find");
  
  insert into roles_permissions(role_name,permission) values("xmanager","sys:k:save");
  insert into roles_permissions(role_name,permission) values("xmanager","sys:k:delete");
  insert into roles_permissions(role_name,permission) values("xmanager","sys:k:update");
  insert into roles_permissions(role_name,permission) values("xmanager","sys:k:find");
  -- 客服人员
  insert into roles_permissions(role_name,permission) values("kmanager","sys:k:find");
  insert into roles_permissions(role_name,permission) values("kmanager","sys:k:update");
  -- 新增人员
  insert into roles_permissions(role_name,permission) values("zmanager","sys:*:find");

2.3SpringBoot整合Shiro

- 创建SpringBoot应用

- 整合Druid和MyBatis

- 整合shiro

  - 添加依赖

    ```xml
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.4.1</version>
    </dependency>


  - 配置Shiro

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
    @Bean
    public JdbcRealm getIniRealm(DataSource dataSource){
        JdbcRealm jdbcRealm = new JdbcRealm();
        jdbcRealm.setDataSource(dataSource);
        //默认开启认证功能,需要手动开启授权功能
        jdbcRealm.setPermissionsLookupEnabled(true);
        return jdbcRealm;
    }
    //SecurityManager要完成验证,需要realm
    @Bean
    public DefaultWebSecurityManager getDefaultWebSecurityManage(JdbcRealm jdbcRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(jdbcRealm);
        return securityManager;
    }
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
        filter.setSecurityManager(securityManager);
        //设置拦截规则
        // anon匿名用户可访问
        //authc 认证用户可以访问
        //user 认证用户可以访问
        //perms 对应权限可以访问
        //role 对应的角色可以访问

        Map<String,String> filterMap=new HashMap<>();
        filterMap.put("/","anon");
        filterMap.put("/login.html","anon");
        filterMap.put("/index.html","anon");
        filterMap.put("/user/login","anon");
        filterMap.put("/user/regist","anon");
        filterMap.put("/static/**","anon");
        filterMap.put("/**","authc");
        filter.setFilterChainDefinitionMap(filterMap);
        filter.setLoginUrl("/login.html");
        filter.setUnauthorizedUrl("/login.html");

        return filter;
    }
}

三、Shiro的标签使用

Shiro提供了可供JSP使用的标签以及Thymeleaf

  - JSP页面中引用:

    ```jsp
    <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
    ```

Thymeleaf模板中引用

1.导入依赖

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

2.配置ShiroConfig

 ```java
    @Configuration
    public class ShiroConfig {
    
        @Bean
        public ShiroDialect getShiroDialect(){
            return new ShiroDialect();
        }
        //...
    }

3.Thymeleaf模版中引入shiro的命名空间

<html xmlns:th="http://www.thymeleaf.org"
          xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
        ...
    </html>

常用标签

- guest,判断用户是否是游客身份,如果是游客身份则显示此标签内容
  <shiro:guest>
      欢迎游客访问,<a href="login.html">登录</a>
  </shiro:guest>

- user,判断用户是否是认证身份,如果是认证身份则显示此标签内容

- principal,获取当前登录用户名
  <shiro:user>
      用户[<shiro:principal/>]欢迎您!
  </shiro:user>

- notAuthenticated/authenticated

- hasRole

- hasPermission

index.html案例

2021-11-23最适合入门的Shiro框架教程(二)(springboot整合Shiro,JdbcRealm表规范,IniRealm,Shiro常用标签,权限菜单实现) 

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    index
    <hr/>
    <shiro:guest>
        欢迎游客访问,<a href="login.html">登录</a>
    </shiro:guest>
    <shiro:user>
        用户[<shiro:principal/>]欢迎您!
        当前用户角色为<Shiro:hasRole name="admin">超级管理员</Shiro:hasRole>
                        <shiro:hasRole name="cmanager">仓管人员</shiro:hasRole>
                        <shiro:hasRole name="xmanager">销售人员</shiro:hasRole>
                        <shiro:hasRole name="kmanager">客服人员</shiro:hasRole>
                        <shiro:hasRole name="zmanager">行政人员</shiro:hasRole>

    </shiro:user>
    <hr/>
    仓库管理
    <ul>
        <shiro:hasPermission name="sys:c:save"><li><a href="#">入库</a></li></shiro:hasPermission>
        <shiro:hasPermission name="sys:c:delete"><li><a href="#">出库</a></li></shiro:hasPermission>
        <shiro:hasPermission name="sys:c:update"><li><a href="#">修改</a></li></shiro:hasPermission>
        <shiro:hasPermission name="sys:c:find"><li><a href="#">查询</a></li></shiro:hasPermission>
    </ul>

    订单管理
    <ul>
        <shiro:hasPermission name="sys:x:save"><li><a href="#">添加订单</a></li></shiro:hasPermission>
        <shiro:hasPermission name="sys:x:delete"><li><a href="#">删除订单</a></li></shiro:hasPermission>
        <shiro:hasPermission name="sys:x:update"><li><a href="#">修改订单</a></li></shiro:hasPermission>
        <shiro:hasPermission name="sys:x:find"><li><a href="#">查询订单</a></li></shiro:hasPermission>
    </ul>

    客户管理
    <ul>
        <shiro:hasPermission name="sys:k:save"><li><a href="#">添加客户</a></li></shiro:hasPermission>
        <shiro:hasPermission name="sys:k:delete"><li><a href="#">删除客户</a></li></shiro:hasPermission>
        <shiro:hasPermission name="sys:k:update"><li><a href="#">修改客户</a></li></shiro:hasPermission>
        <shiro:hasPermission name="sys:k:find"><li><a href="#">查询客户</a></li></shiro:hasPermission>
    </ul>

</body>
</html>
上一篇:RODE: LEARNING ROLES TO DECOMPOSE MULTI-AGENT TASKS


下一篇:HEOI2016 序列