SpringBoot整合Shiro+mybatis-plus
阿新 • • 發佈:2019-02-13
原始碼地址: link
一、新增依賴
<?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">
<modelVersion>4.0.0</modelVersion>
< groupId>com.joecy</groupId>
<artifactId>springboot_mybatis-plus_shiro</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot_mybatis-plus_shiro</name>
<description>Spring Boot整合Mybitis Plus和Shiro小Demo</ description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties >
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<mybatisplus-spring-boot-starter.version>1.0.5</mybatisplus-spring-boot-starter.version>
<mybatisplus.version>2.1.4</mybatisplus.version>
<shiro-spring.version>1.3.2</shiro-spring.version>
<druid.version>1.0.18</druid.version>
<lombok.version>1.18.2</lombok.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--沒有此依賴shiro註解許可權會失效-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!--lombok外掛使用依賴-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!--mybatis plus依賴-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatisplus-spring-boot-starter</artifactId>
<version>${mybatisplus-spring-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<!--資料來源相關-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--shiro依賴-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro-spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--熱部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
</dependencies>
</project>
二、application.properties配置檔案
server.port=8080
# 資料庫訪問配置
# 主資料來源,預設的
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus_shiro_test?Unicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
# 下面為連線池的補充設定,應用到上面所有資料來源中
# 初始化大小,最小,最大
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
# 配置獲取連線等待超時的時間
spring.datasource.maxWait=60000
# 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000
# 配置一個連線在池中最小生存的時間,單位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
# 開啟PSCache,並且指定每個連線上PSCache的大小
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
# 配置監控統計攔截的filters,去掉後監控介面sql無法統計,'wall'用於防火牆
spring.datasource.filters=stat,wall,log4j
# 通過connectProperties屬性來開啟mergeSql功能;慢SQL記錄
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合併多個DruidDataSource的監控資料
#spring.datasource.useGlobalDataSourceStat=true
#整合Freemark
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=true
spring.freemarker.expose-session-attributes=true
spring.freemarker.request-context-attribute=request
spring.freemarker.allow-session-override=true
#Mybatis配置
mybatis-plus.mapper-locations=classpath:mappers/*.xml
#mybatis-plus的model包
mybatis-plus.typeAliasesPackage=com.joecy.entity
#global-config:
#主鍵型別 0:"資料庫ID自增", 1:"使用者輸入ID",2:"全域性唯一ID (數字型別唯一ID)", 3:"全域性唯一ID UUID";
#id-type: 2
mybatis-plus.global-config.id-type=0
#駝峰式命名對映
mybatis-plus.global-config.db-column-underline=true
三、mybatis-plus相關
1 新建資料庫表對應的model,以SecUser為例
/**
* 使用者表
* 需要繼承mybatis-plus的Model<>抽象類
*/
@Data
public class SecUser extends Model<SecUser> {
//指定id
@TableId
private Integer id;
private String username;
private String password;
@TableField(exist = false)
private List<SecRole> roles;
//實現預設id方法
//若一個表沒有id 直接return null即可
@Override
protected Serializable pkVal() {
return this.id;
}
}
2 建立SecUser對應Mapper SecUserMapper
//必須新增mybatis的@Mapper註解
@Mapper
public interface SecUserMapper extends BaseMapper<SecUser> {
}
至此該model就可以正常使用了,具體使用方法很簡單,參照mybatis-plus官網:link
四、現在開始Shiro配置
1 建立MyShiroRealm
//實現AuthorizingRealm介面使用者使用者認證
public class MyShiroRealm extends AuthorizingRealm {
//角色許可權和對應許可權新增
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
//新增角色和許可權
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
System.out.println(principalCollection.getPrimaryPrincipal());
SecUser user= (SecUser) principalCollection.getPrimaryPrincipal();
//儲存所有角色名
Set<String> allRoles = new HashSet<>();
//儲存所有許可權名
Set<String> allPermissions = new HashSet<>();
//查詢對應角色
List<SecUserRole> secUserRoles = new SecUserRole().selectList(new EntityWrapper().eq("user_id", user.getId()));
for (SecUserRole userRole:secUserRoles) {
SecRole role = new SecRole();
role.setId(userRole.getRoleId());
role = role.selectById();
allRoles.add(role.getName());
//查詢所有許可權
List<SecPermission> permissions = new ArrayList<>();
List<SecRolePermission> rolePermissions = new SecRolePermission().selectList(new EntityWrapper().eq("role_id", role.getId()));
for (SecRolePermission rolePermission:rolePermissions) {
SecPermission permission = new SecPermission();
permission.setId(rolePermission.getPermissionId());
permission = permission.selectById();
allPermissions.add(permission.getName());
}
}
//新增角色
simpleAuthorizationInfo.addRoles(allRoles);
simpleAuthorizationInfo.addStringPermissions(allPermissions);
System.out.println(user);
return simpleAuthorizationInfo;
}
//使用者認證
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 1、登入認證的方法需要先執行,需要用他來判斷登入的使用者資訊是否合法
String username = (String) token.getPrincipal(); // 取得使用者名稱
// 需要通過使用者名稱取得使用者的完整資訊,利用業務層操作
SecUser user = null;
try {
user = new SecUser().selectOne(new EntityWrapper().eq("username",username));
} catch (Exception e) {
e.printStackTrace();
}
if (user == null) {
throw new UnknownAccountException("該使用者名稱稱不存在!");
} else { // 進行密碼的驗證處理
String password =new String((char[]) token.getCredentials());
// 將資料庫中的密碼與輸入的密碼進行比較,這樣就可以確定當前使用者是否可以正常登入
if (user.getPassword().equals(password)) { // 密碼正確
AuthenticationInfo auth = new SimpleAuthenticationInfo(user, password, "memberRealm");
return auth;
} else {
throw new IncorrectCredentialsException("密碼錯誤!");
}
}
}
}
2 建立Shiro配置類ShiroConfig
@Configuration
public class ShiroConfig {
//將自己的驗證方式加入容器
@Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
return myShiroRealm;
}
//許可權管理,配置主要是Realm的管理認證
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
//Filter工廠,設定對應的過濾條件和跳轉條件
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 必須設定 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 如果不設定預設會自動尋找Web工程根目錄下的"/login.jsp"頁面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登入成功後要跳轉的連結
shiroFilterFactoryBean.setSuccessUrl("/index");
// 許可權控制map.
LinkedHashMap<String, String> filterChainDefinitionMap=new LinkedHashMap<>();
filterChainDefinitionMap.put("/css/**", "anon"); //表示可以匿名訪問
filterChainDefinitionMap.put("/js/**", "anon"); //表示可以匿名訪問
filterChainDefinitionMap.put("/img/**", "anon"); //表示可以匿名訪問
filterChainDefinitionMap.put("/font/**", "anon"); //表示可以匿名訪問
filterChainDefinitionMap.put("/images/**", "anon"); //表示可以匿名訪問
filterChainDefinitionMap.put("/login", "anon"); //表示可以匿名訪問
filterChainDefinitionMap.put("/user_login", "anon");
filterChainDefinitionMap.put("/logout*","logout");
filterChainDefinitionMap.put("/error","anon");
filterChainDefinitionMap.put("/**","authc");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
//加入註解的使用,不加入這個註解不生效
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
System.out.println("開啟了shiro註解功能");
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authoriz