注; 该代码只适用于以下pom配置(不能说自己懒得 重新搭建一个shiro-web整合shiro-spring环境,只能告诉自己怎么简单怎么来,shiro-web整合shiro-spring与shiro-redis环境要写太多代码了
),
以前的版本差不多也可以参考代码配置,其实核心就是RedisManager 这个类对象而已,就是重新注入spring redis配置,覆盖 shiro redis默认配置,方便统一维护
<!-- springboot shiro 最新版-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.10.1</version>
</dependency>
<!--springboot shiro-redis 最新版-->
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis-spring-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<!-- springboot shiro-redis 最新版的 shiro 版本是1.6.0 强制统一设置为 1.10.1 最新版-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.10.1</version>
</dependency>
<!--springboot redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置 shiro-redis 连接配置交由springboot redis管理核心代码
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.ShiroRedisAutoConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* <p>@类名描述 :配置shiro redis 由 springboot redis管理</p>
* <p>@类名 :BootShiroRedisConfiguration.java</p>
* <p>@开发者 :深渊码头</p>
* <p>@开发者邮箱 :itgsvip@qq.com</p>
* <p>@开发版本 :1.0</p>
* <p>@Copyright : itgsvip @ 2021 </p>
*/
@Configuration
public class BootShiroRedisConfiguration extends ShiroRedisAutoConfiguration {
/**
* 注入springboot redis配置
*/
@Autowired
private RedisProperties redisProperties;
/**
* RedisManager配置交由springBootRedis管理
*/
@Bean
public RedisManager redisManager() {
Long timeout = Long.valueOf(redisProperties.getTimeout().toMillis());
RedisManager standaloneManager = new RedisManager();
standaloneManager.setHost(redisProperties.getHost() + ":" + redisProperties.getPort());
standaloneManager.setTimeout(timeout.intValue());
standaloneManager.setPassword(redisProperties.getPassword());
standaloneManager.setDatabase(redisProperties.getDatabase());
return standaloneManager;
}
}
shiro 配置
import org.apache.shiro.session.mgt.eis.SessionDAO;
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.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;
/**
* <p>@方法名描述 : Shiro过滤器 </p>
* <per>
* <code>
* anon ===> 开放路径,允许匿名访问,不需要权限和不需要登录就可以访问
* authc ===> 需要登录后才可以访问路径
* </code>
* </per>
* @return
*/
@Bean("shiroFilterChainDefinition")
public ShiroFilterChainDefinition shiroFilterChainDefinition() {
DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition();
chainDefinition.addPathDefinition("/api/doLogin", "anon");
chainDefinition.addPathDefinition("/login", "anon");
chainDefinition.addPathDefinition("/**", "authc");
return chainDefinition;
}
/**
* <p>@Bean("authorizer") 是必须的</>
* <p>自定义 Realm</>
* @return 自定义 SampleRealm 对象
*/
@Bean("authorizer")
SampleRealm sampleRealm() {
return new SampleRealm();
}
/**
* <p>重写SessionDAO</>
* <p>SessionDAO 默认实现交由 RedisSessionDAO 实现管理</p>
*/
@Override
protected SessionDAO sessionDAO() {
return redisSessionDAO;
}
}
自定义SampleRealm 就是查询数据数据是否存在登录用户的业务代码 需要继承 AuthorizingRealm 类,参考代码,我的是测试搭建环境架构使用,所以写死了
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 org.springframework.stereotype.Component;
import com.itgsvip.pojo.UserVo;
/**
* <p>@类名描述 :自定义Realm </p>
* <p>@类名 :SampleRealm.java</p>
* <p>@开发者 :深渊码头</p>
* <p>@开发者邮箱 :itgsvip@qq.com</p>
* <p>@开发版本 :1.0</p>
* <p>@Copyright : itgsvip @ 2022 </p>
*
*/
@Component
public class SampleRealm extends AuthorizingRealm {
// 举例业务
// @Autowired
// private UserDAO userDao;
/**
* <p>@重写方法名描述 : 授权查询,有shiro注解的方法都会走这里,去验证权限 </p>
* @param principals SecurityUtils.getSubject()的集合
* @return 授权信息
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
/**
* 将PrimaryPrincipal转换为UserVo对象
* UserVo对象怎么来?可以看 当前类 的 doGetAuthenticationInfo
* return new SimpleAuthenticationInfo(user, password, getName());
*/
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;
}
/**
* <p>@重写方法名描述 :登录认证信息 </p>
* @param authcToken
* @return
* @throws AuthenticationException
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
String userName = token.getUsername();
String password = String.valueOf(token.getPassword());
//举例你的业务,查询用户信息
//UserInfo user = userDao.find(userName ,password )
//又或者
//UserInfo user = userDao.find(userName )
/**
* 模拟数据库账号,管理员角色
*/
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());
}
}
UserVO
properties配置
#---------spring.redis配置--------------------------------------
spring.redis.host=
spring.redis.port=
spring.redis.password=
spring.redis.database=1
spring.redis.timeout=5000
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-wait=-1
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.min-idle=0
#---------spring.redis配置--------------------------------------
#---------shiro配置--------------------------------------
#登录页面
shiro.loginUrl=/login
#无权限访问
shiro.unauthorizedUrl=/error
shiro.userNativeSessionManager=true
#禁用URL会话重写
shiro.sessionManager.sessionIdUrlRewritingEnabled=false
#自定义cookie名字,默认JSESSIONID
shiro.sessionManager.cookie.name=authorization
#---------shiro配置--------------------------------------
#--------------------shiro-redis配置------------------------
#实体类id,默认是id,找不到id则会报错
shiro-redis.cache-manager.principal-id-field-name=userId
#自定义redis关键字前缀的会话管理
shiro-redis.session-dao.key-prefix=token:user-session:
#自定义redis关键字前缀缓存管理
shiro-redis.cache-manager.key-prefix=token:authorization:
#--------------------shiro-redis配置------------------------