【笔记2】SpringBoot快速整合ShiroRedis与Thymeleaf(完整版)

博客代码下载

 SpringBoot快速整合ShiroRedis与Thymeleaf(完整版)免费下载-Java文档类资源-CSDN下载

pom.xml

<dependency>
	<groupId>org.crazycake</groupId>
	<artifactId>shiro-redis-spring-boot-starter</artifactId>
	<version>3.3.1</version>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

代码实现

一.重写ShiroWebAutoConfiguration类

import org.apache.shiro.mgt.SessionsSecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.config.web.autoconfigure.ShiroWebAutoConfiguration;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.ServletContainerSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BootShiroRedisAutoConfiguration extends ShiroWebAutoConfiguration {

	@Autowired
	RedisSessionDAO redisSessionDAO;

	@Autowired
	RedisCacheManager redisCacheManager;

	@Bean("shiroFilterChainDefinition")
	public ShiroFilterChainDefinition shiroFilterChainDefinition() {
		DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
		chainDefinition.addPathDefinition("/api/doLogin", "anon");//你不需要拦截路径
		chainDefinition.addPathDefinition("/**", "authc");//你需要拦截的路径
		return chainDefinition;
	}

	@Bean("authorizer")//自定义SampleRealm,必须配置
	public SampleRealm sampleRealm() {
		return new SampleRealm();
	}
    //重写 SessionManager 方法
	@Override
	protected SessionManager sessionManager() {
		if (useNativeSessionManager) {
			DefaultWebSessionManager nativeSessionManager = (DefaultWebSessionManager) nativeSessionManager();
			nativeSessionManager.setSessionDAO(redisSessionDAO);
			return nativeSessionManager;
		}
		return new ServletContainerSessionManager();
	}
    //重写 SessionsSecurityManager 方法
	protected SessionsSecurityManager securityManager(SampleRealm realms) {
		DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) createSecurityManager();
		securityManager.setRealm(realms);
		securityManager.setSessionManager(sessionManager());
		securityManager.setCacheManager(redisCacheManager);
		return securityManager;
	
	}

}

二、自定义Realm,SampleRealm.java


import java.util.HashSet;
import java.util.Set;

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.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection; 
import cn.itgsvip.pojo.UserVo;

public class SampleRealm extends AuthorizingRealm {

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		UserVo principal = (UserVo) principals.getPrimaryPrincipal();
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
		if ("admin".equals(principal.getUserName())) {
			authorizationInfo.addRole("admin");
			Set<String> permissions = new HashSet<String>();
			permissions.add("admin:del");//权限
			permissions.add("admin:find");
			authorizationInfo.addStringPermissions(permissions);
		}
		if ("user".equals(principal.getUserName())) { 
			authorizationInfo.addRole("user");
			Set<String> permissions = new HashSet<String>();
			permissions.add("user:del");
			permissions.add("user:find");
			authorizationInfo.addStringPermissions(permissions);
		}
		if ("adminAndUser".equals(principal.getUserName())) {
			Set<String> roles = new HashSet<String>();
			roles.add("admin");//管理员角色
			roles.add("user");//用户角色
			authorizationInfo.addRoles(roles);
			Set<String> permissions = new HashSet<String>();
			permissions.add("admin:del");//权限
			permissions.add("admin:find");
			permissions.add("user:del");
			permissions.add("user:find");
			authorizationInfo.addStringPermissions(permissions);
		}
		return authorizationInfo;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
			throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		String userName = token.getUsername();
		String password = String.valueOf(token.getPassword());

		UserVo user = new UserVo();
		if ("admin".equals(userName)) {
			user.setUserId("10001");
			user.setUserName(userName);
			user.setPassWord(password);
		}
		if ("user".equals(userName)) {
			user.setUserId("10002");
			user.setUserName(userName);
			user.setPassWord(password);
		}
		if ("adminAndUser".equals(userName)) {
			user.setUserId("10000");
			user.setUserName(userName);
			user.setPassWord(password);
		}
		return new SimpleAuthenticationInfo(user, password, getName());
	}
}

三、application.properties配置

(1)shiro配置

官方文档地址 Apache Shiro | Simple. Java. Security.

#---------shiro配置--------------------------------------
#登录页面
shiro.loginUrl=/login
#无权限访问
shiro.unauthorizedUrl=/error
#将回话sessions交给shiro管理
shiro.userNativeSessionManager=true
#禁用URL会话重写
shiro.sessionManager.sessionIdUrlRewritingEnabled=false
#自定义cookie名字,默认JSESSIONID
shiro.sessionManager.cookie.name=Authorization
#---------shiro配置--------------------------------------

(2)shiro-redis配置

官方文档地址:shiro-redis | shiro only provide the support of ehcache and concurrentHashMap. Here is an implement of redis cache can be used by shiro. Hope it will help you!

#--------------------shiro-redis配置------------------------
#redis地址
shiro-redis.redis-manager.host=127.0.0.1:6379
#redis密码
#shiro-redis.redis-manager.password=12345
#用户信息存入redis第几个库
shiro-redis.redis-manager.database=5
#实体类id,默认是id,找不到id则会报错
shiro-redis.cache-manager.principal-id-field-name=userId
#自定义redis关键字前缀的会话管理,默认shiro:session:	
shiro-redis.session-dao.key-prefix=token:user-session:
#自定义redis关键字前缀缓存管理,默认shiro:cache:
shiro-redis.cache-manager.key-prefix=token:authorization:
#--------------------shiro-redis配置------------------------

(3)Thymeleaf,不需要配置,使用默认的配置既可

是的,已经集成完毕

题外话:为什么这样实现?

在你不理解为什么这样搭建的时候,下面是代码的分析步骤

1( 因为我前面发布的四篇博客都是和shiro有关的,其实都是存在问题的!比如使用 shiro-redis-spring-boot-starter 的时候,导致shiro官方提供的配置失效,__ 这是因为 shiro-redis-spring-boot-starter  重写了shiro官方提供的SessionManagerSecurityManager方法,没有把shiro的配置配置进去,才会导致shiro配置无效,这才是病因。

2( 我重新看了 shiro-redis-spring-boot-starter shiro-spring-boot-web-starter 的源码实现,我一步一步来到了shiro-spring-boot-web-starter 实现SessionManagerSecurityManager的源码

3( 刚好shiro-redis官网有个说明,意思是,如果你不想创建shiro配置,shiro-redis-spring-boot-starter 帮忙我们创建配置,帮忙我们创建配置的时候把shiro提供的配置全部干掉了,所以又回到了 __ 这个问题 。

4( 既然知道问题所在了,我就动手把他们重新调整一下,就是重写了ShiroWebAutoConfiguration的SessionManagerSecurityManager方法,重写了但是并没有完全重写,只是把shiro-redis-spring-boot-starter 的配置添加进去,这样在不破坏ShiroShiro-Redis的配置下,然后就成功的解决了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值