SpringBoot+Shiro+mybatis整合实战

编程

SpringBoot+Shiro+mybatis整合

1. 使用Springboot版本2.0.4 与shiro的版本

   引入springboot和shiro依赖   

<?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.smile</groupId>

<artifactId>spring-demo</artifactId>

<version>1.0-SNAPSHOT</version>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.0.4.RELEASE</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<properties>

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<java.version>1.8</java.version>

</properties>

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

</dependency>

<!--常用工具类 -->

<dependency>

<groupId>org.apache.commons</groupId>

<artifactId>commons-lang3</artifactId>

</dependency>

<!-- mysql所需的配置 -->

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

</dependency>

<dependency>

<groupId>org.mybatis.spring.boot</groupId>

<artifactId>mybatis-spring-boot-starter</artifactId>

<version>1.3.2</version>

</dependency>

<!--阿里数据库连接池 -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid-spring-boot-starter</artifactId>

<version>1.1.10</version>

</dependency>

<!-- Redis客户端 -->

<dependency>

<groupId>redis.clients</groupId>

<artifactId>jedis</artifactId>

</dependency>

<!-- 读取资源文件所需的配置 -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-configuration-processor</artifactId>

<optional>true</optional>

</dependency>

<!-- 引入thymeleaf模板依赖 -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-thymeleaf</artifactId>

</dependency>

<!-- pagehelper 分页插件 -->

<dependency>

<groupId>com.github.pagehelper</groupId>

<artifactId>pagehelper-spring-boot-starter</artifactId>

<version>1.2.5</version>

</dependency>

<!-- 阿里JSON解析器 -->

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>fastjson</artifactId>

<version>1.2.47</version>

</dependency>

<!-- 集成shiro -->

<dependency>

<groupId>org.apache.shiro</groupId>

<artifactId>shiro-spring</artifactId>

<version>1.4.0</version>

</dependency>

<!-- https://mvnrepository.com/artifact/org.crazycake/shiro-redis -->

<dependency>

<groupId>org.crazycake</groupId>

<artifactId>shiro-redis</artifactId>

<version>3.1.0</version>

</dependency>

<!-- 打印SQL语句-->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-jpa</artifactId>

</dependency>

</dependencies>

</project>

2. 添加相应的配置

server:

port: 8183

spring:

thymeleaf:

mode: HTML

encoding: utf-8

cache: false

datasource:

driver-class-name: com.mysql.jdbc.Driver

url: jdbc:mysql://192.168.144.128:3306/spring_shiro?serverTimezone=GMT&useUnicode=true&characterEncoding=utf-8&useSSL=true

#url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false

username: root

password: root

type: com.alibaba.druid.pool.DruidDataSource

maxActive: 20

initialSize: 1

maxWait: 60000

poolPreparedStatements: true

maxPoolPreparedStatementPerConnectionSize: 20

minIdle: 1

timeBetweenEvictionRunsMillis: 60000

minEvictableIdleTimeMillis: 300000

validationQuery: select 1 from dual

testWhileIdle: true

testOnBorrow: false

jackson:

time-zone: GMT+8

date-format: yyyy-MM-dd HH:mm:ss

jpa:

database: mysql

show-sql: true

#日志级别打印

logging:

level:

com.example.demo: debug

org.springframework: WARN

org.spring.springboot.dao: debug

# MyBatis

mybatis:

typeAliasesPackage: com.example.demo

mapperLocations: classpath:mybatis/**/*Mapper.xml

configLocation: classpath:mybatis/mybatis-config.xml

# PageHelper

pagehelper:

helperDialect: mysql

reasonable: true

supportMethodsArguments: true

params: count=countSql

3. 将相关配置@Bean注入容器

package com.example.demo.config;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;

import org.apache.shiro.mgt.SecurityManager;

import org.apache.shiro.session.mgt.SessionManager;

import org.apache.shiro.spring.web.ShiroFilterFactoryBean;

import org.apache.shiro.web.mgt.DefaultWebSecurityManager;

import org.crazycake.shiro.RedisCacheManager;

import org.crazycake.shiro.RedisManager;

import org.crazycake.shiro.RedisSessionDAO;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.LinkedHashMap;

import java.util.Map;

/**

* @时间 2019/11/25 17:17

* @作者 liutao

* @描述

*/

@Configuration

publicclass ShiroConfig {

/**

* 设置过滤器

* @param securityManager

* @return

*/

@Bean

public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager){

ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();

factoryBean.setSecurityManager(securityManager);

// 设置需要进行登录的路径API

factoryBean.setLoginUrl("/pub/need_login");

// 若是使用前后端分离,则不需要进行设置该方法

factoryBean.setSuccessUrl("/");

// 没有进行授权,返回的API

factoryBean.setUnauthorizedUrl("/pub/not_permit");

// 自定义过滤器

Map<String, String> filterMap = new LinkedHashMap<>();

// 设置退出的过滤器

filterMap.put("/logout", "logout");

// 不需要进行授权就可以进行访问,游客都可以进行访问的API

filterMap.put("/pub/**", "anon");

// 需要进行授权才可以进行访问的API接口

filterMap.put("/authc/**", "authc");

// 有对应的角色才可以进行访问

filterMap.put("/admin/**", "roles[admin]");

// 设置最后的拦截器,需要进行授权才可以进行访问

filterMap.put("/**","authc");

factoryBean.setFilterChainDefinitionMap(filterMap);

return factoryBean;

}

/**

* 设置安全管理器

* @return

*/

@Bean

public SecurityManager securityManager(){

DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();

securityManager.setSessionManager(sessionManager());

securityManager.setRealm(customRealm());

securityManager.setCacheManager(cacheManage());

return securityManager;

}

/**

* 自定义Realm

* @return

*/

@Bean

public CustomRealm customRealm(){

CustomRealm customRealm = new CustomRealm();

// 设置密码的加密

customRealm.setCredentialsMatcher(hashedCredentialsMatcher());

return customRealm;

}

/**

* 设置sessionId的管理器 (前后端分离,要进行获取Token)

* @return

*/

@Bean

public SessionManager sessionManager(){

CustomSessionManager sessionManager = new CustomSessionManager();

// 设置sessionDAO -- 里面定义了自定义SessionId

sessionManager.setSessionDAO(redisSessionDAO());

return sessionManager;

}

/**

* 设置密码加密

* @return

*/

@Bean

public HashedCredentialsMatcher hashedCredentialsMatcher(){

HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();

// 密码算法

matcher.setHashAlgorithmName("md5");

// 加密散列次数

matcher.setHashIterations(3);

return matcher;

}

/**

* 将会话SessionId保存到Redis里面,可以提高性能

* @return

*/

public RedisSessionDAO redisSessionDAO(){

RedisSessionDAO dao = new RedisSessionDAO();

dao.setRedisManager(redisManager());

dao.setSessionIdGenerator(new CustomSessionIdGenerator());

return dao;

}

/**

* 接入Redis数据库

* @return

*/

public RedisManager redisManager(){

RedisManager redisManager = new RedisManager();

redisManager.setHost("127.0.0.1");

redisManager.setPort(6379);

return redisManager;

}

/**

* 缓存管理

* @return

*/

@Bean

public RedisCacheManager cacheManage(){

RedisCacheManager cacheManager = new RedisCacheManager();

cacheManager.setRedisManager(redisManager());

// 设置过期时间,单位是秒

cacheManager.setExpire(60);

return cacheManager;

}

/**

* 加入请求头 前后端分离

* @return

*/

@Bean

public WebMvcConfigurer webMvcConfigurer(){

returnnew WebMvcConfig();

}

}

4.创建CustomRealm类继承AuthorizingRealm,实现用户登录认证和权限鉴权

package com.example.demo.config;

import com.example.demo.entity.User;

import com.example.demo.service.UserService;

import org.apache.shiro.authc.AuthenticationException;

import org.apache.shiro.authc.AuthenticationInfo;

import org.apache.shiro.authc.AuthenticationToken;

import org.apache.shiro.authc.SimpleAuthenticationInfo;

import org.apache.shiro.authz.AuthorizationInfo;

import org.apache.shiro.realm.AuthorizingRealm;

import org.apache.shiro.subject.PrincipalCollection;

import org.springframework.beans.factory.annotation.Autowired;

/**

* @时间 2019/11/25 17:17

* @作者 liutao

* @描述

*/

publicclass CustomRealm extends AuthorizingRealm {

@Autowired

private UserService userService;

/**

* 鉴权

* @param principals

* @return

*/

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

String name = (String) principals.getPrimaryPrincipal();

    //若是使用Redis和cache,获取信息转成用户对象

    // User user= (User) principals.getPrimaryPrincipal();

    returnnull;

}

/**

* 登录认证

* @param token

* @return

* @throws AuthenticationException

*/

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

String name = (String) token.getPrincipal();

User user = userService.selectUserByName(name);

if(user == null){

returnnull;

}

     // 若是加入Redis和Cache缓存的管理的话,需要返回 用户对象
     //new SimpleAuthenticationInfo(user,user.getPassword(),getName());

    returnnew SimpleAuthenticationInfo(name,user.getPassword(),getName());

}

}

5. 创建CustomSessionManager继承DefaultWebSessionManager,可以进行实现Token,进行重写

package com.example.demo.config;

import org.apache.shiro.web.servlet.ShiroHttpServletRequest;

import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;

import org.apache.shiro.web.util.WebUtils;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import java.io.Serializable;

/**

* @时间 2019/11/25 17:18

* @作者 liutao

* @描述

*/

publicclass CustomSessionManager extends DefaultWebSessionManager {

privatestaticfinal String AUTHORIZATION = "token";

public CustomSessionManager(){

super();

}

@Override

protected Serializable getSessionId(ServletRequest request, ServletResponse response) {

String sessionId = WebUtils.toHttp(request).getHeader(AUTHORIZATION);

if(sessionId != null){

request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE,

ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);

request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionId);

//automatically mark it valid here. If it is invalid, the

//onUnknownSession method below will be invoked and we"ll remove the attribute at that time.

request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);

return sessionId;

}else{

returnsuper.getSessionId(request,response);

}

}

}

6. 实现自定义SessionId,创建CustomSessionIdGenerator类实现 SessionIdGenerator

package com.example.demo.config;

import org.apache.shiro.session.Session;

import org.apache.shiro.session.mgt.eis.SessionIdGenerator;

import java.io.Serializable;

import java.util.UUID;

/**

* @时间 2019/11/26 16:30

* @作者 liutao

* @描述

*/

publicclass CustomSessionIdGenerator implements SessionIdGenerator {

privatefinal String PREFIX_SESSIONID = "cc0504";

public CustomSessionIdGenerator(){

super();

}

@Override

public Serializable generateId(Session session) {

return PREFIX_SESSIONID + UUID.randomUUID().toString().replaceAll("-","");

}

}

7.前后端分离,在Header里面加入相应的数据信息

package com.example.demo.config;

import org.springframework.web.servlet.config.annotation.CorsRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**

* @时间 2019/11/25 19:27

* @作者 liutao

* @描述

*/

publicclass WebMvcConfig implements WebMvcConfigurer {

@Override

publicvoid addCorsMappings(CorsRegistry registry) {

registry.addMapping("/**")

.allowedOrigins("*") //可访问ip,ip最好从配置文件中获取,

.allowedMethods("PUT", "DELETE","GET","POST")

.allowedHeaders("*")

.exposedHeaders("access-control-allow-headers","access-control-allow-methods","access-control-allow-origin", "access-control-max-age","X-Frame-Options")

.allowCredentials(false).maxAge(3600);

}

}

8. mybatis的配置

# MyBatis

mybatis:

typeAliasesPackage: com.example.demo

mapperLocations: classpath:mybatis/**/*Mapper.xml

configLocation: classpath:mybatis/mybatis-config.xml

mybatis-config.xml中的内容:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

<settings>

<setting name="cacheEnabled" value="true" /> <!-- 全局映射器启用缓存 -->

<setting name="useGeneratedKeys" value="false" /> <!-- 不允许 JDBC 支持自动生成主键 -->

<setting name="defaultExecutorType" value="REUSE" /> <!-- 配置默认的执行器 -->

<!--<setting name="logImpl" value="SLF4J" />--> <!-- 指定 MyBatis 所用日志的具体实现 -->

<setting name="logImpl" value="STDOUT_LOGGING" /> <!-- 在控制台打印SQL语句 -->

<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> 驼峰式命名 -->

</settings>

</configuration>

基础Mapper.xml文件内容

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.example.demo.mapper.UserMapper">

<resultMap id="userResultMap" type="User">

<result column="id" property="id"/>

<result column="name" property="name"/>

<result column="password" property="password"/>

<result column="salt" property="salt"/>

</resultMap>

<select id="selectAllUsers" resultMap="userResultMap">

select * from sys_user

</select>

<select id="selectUserByName" resultMap="userResultMap">

select * from sys_user where name = #{name}

</select>

</mapper>

以上是 SpringBoot+Shiro+mybatis整合实战 的全部内容, 来源链接: utcz.com/z/511974.html

回到顶部