参考了markerHub的开源项目,大家可以去看一下,我觉得整个开发过程很完整。
基本上也是参照开源项目写的,这个部分我不是很熟悉,即使我看完了理论教程,也不是很能写出来,所以就模仿下写了。
shrio+jwt参考视频
第一步:在pom文件导入shiro-redis的starter包:还有jwt的工具包,简化开发,引入hutool工具包。
Hutool的存在就是为了减少代码搜索成本,避免网络上参差不齐的代码出现导致的bug。
org.crazycake shiro-redis-spring-boot-starter3.2.1 cn.hutool hutool-all5.3.3 io.jsonwebtoken jjwt0.9.1
第二步:重写自己的SessionManager或SessionsSecurityManager。
引入RedisSessionDAO和RedisCacheManager,为了解决shiro的权限数据和会话信息能保存到redis中,实现会话共享。
package com.hotin.server.config; import org.apache.shiro.mgt.SessionsSecurityManager; import org.apache.shiro.realm.Realm; import org.apache.shiro.session.mgt.SessionManager; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.crazycake.shiro.RedisCacheManager; import org.crazycake.shiro.RedisSessionDAO; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.List; @Configuration public class ShiroConfig { @Bean public SessionManager sessionManager(RedisSessionDAO redisSessionDAO) { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); // inject redisSessionDAO sessionManager.setSessionDAO(redisSessionDAO); // other stuff... return sessionManager; } @Bean public SessionsSecurityManager securityManager(Listrealms, SessionManager sessionManager,RedisCacheManager redisCacheManager) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(realms); //inject sessionManager securityManager.setSessionManager(sessionManager); // inject redisCacheManager securityManager.setCacheManager(redisCacheManager); // other stuff... return securityManager; } }
第三步:定义自己的AccountRealm,上面的方法用于认证,下面的方法用于授权,记得加上Component注解,注入到容器里面。
- Realm:一般我们都需要去实现自己的Realm ,可以有1个或多个 Realm,即当我们进行登录认证时所获取的安全数据来源(帐号/密码)
package com.hotin.server.config.shiro; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; @Component public class AccountRealm extends AuthorizingRealm { @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { return null; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException { return null; } }
第三步:将自己的AccountRealm更换ShiroConfig的Realm
@Bean public SessionsSecurityManager securityManager(AccountRealm accountRealm, SessionManager sessionManager, RedisCacheManager redisCacheManager) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(accountRealm); //inject sessionManager securityManager.setSessionManager(sessionManager); // inject redisCacheManager securityManager.setCacheManager(redisCacheManager); // other stuff... return securityManager; }
现在的层级目录图,我喜欢把组件和配置类分开,这样子可以快速找到组件更改业务逻辑
现在启动的话会报错
下一步,我们要添加ShirofilterChainDefinitions和ShiroFilterFactoryBean。
项目启动时,shrio 通过自己的org.apache.shiro.spring.web.ShiroFilterFactoryBean 类的
filterChainDefinitions(授权规则定义)属性转换为一个filterChainDefinitionMap,转换完成后
交给ShiroFilterFactoryBean 保管。
其中filterChainDefinitions 就是指定过滤规则的,一般公共配置使用配置文件,例如jss css img这些资源文件是不拦截的,相关业务的url配置到数据库,有过滤器查询数据库进行权限判断。
shiro自带的过滤器
anon: 无需认证即可访问
authc: 需要认证才可访问
user: 点击“记住我”功能可访问
perms: 拥有权限才可以访问
role: 拥有某个角色权限才能访问
@Bean public ShiroFilterChainDefinition shiroFilterChainDefinition() { DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition(); MapfilterMap = new linkedHashMap<>(); filterMap.put(" Map filterMap = shiroFilterChainDefinition.getFilterChainMap(); shiroFilter.setFilterChainDefinitionMap(filterMap); return shiroFilter; }
需要注意的是:
SecurityManager需要我们自己手动引入,不然就会报红
import org.apache.shiro.mgt.SecurityManager;
启动成功后,我们访问http://localhost:8081/user/index,然后就会有问题了,成功被拦截的是404错误,而有些却是500错误,这是为什么呢,这就要讲到shiro-redis的默认连接配置了,默认的会访问127.0.0.0:6379,也就是本地redis,那我们本地没有redis的自然就访问不了,那如何访问虚拟机上的redis呢,就需要进行另外的配置了。
redis无法连接问题
接下来就要开始进行jwtFilter过滤器代码实现了。
把过滤器改回jwt,注释也取消掉。
@Bean public ShiroFilterChainDefinition shiroFilterChainDefinition() { DefaultShiroFilterChainDefinition chainDefinition = new DefaultShiroFilterChainDefinition(); MapfilterMap = new linkedHashMap<>(); filterMap.put("/**", "jwt"); // 主要通过注解方式校验权限 chainDefinition.addPathDefinitions(filterMap); return chainDefinition; } @Bean("shiroFilterFactoryBean") public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager, ShiroFilterChainDefinition shiroFilterChainDefinition) { ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean(); shiroFilter.setSecurityManager(securityManager); Map filters = new HashMap<>(); filters.put("jwt", jwtFilter); shiroFilter.setFilters(filters); Map filterMap = shiroFilterChainDefinition.getFilterChainMap(); shiroFilter.setFilterChainDefinitionMap(filterMap); return shiroFilter; }
自动注入我们的jwtFilter
心得@Autowired private JwtFilter jwtFilter;
明天写完整个登录流程, 今天的话,学了shiro一脸懵逼,简直了,看得懂一点,不会写,知道有什么,但是不知道作用是什么,他跟什么关联在一起,估计后面还会出一个shiro的教程,我觉得理解透彻点,用比较直观的图或者文字讲述,也是对自己的一个挑战吧,不是原地踏步就是成功的一小步,希望明天能写完吧,呜呜呜,看着别人的教程,我也一脸懵逼,只能一个个去搜,看下是什么,头脑炸裂,眼睛好痛,对着电脑,眼睛苦涩,不要掉头发就行
2021/11/23 0:44 更
ps: 属实是记得写时间在写上去。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)