基于SpringBoot+Vue的博客网站(由0开始)-----第七天

基于SpringBoot+Vue的博客网站(由0开始)-----第七天,第1张

基于SpringBoot+Vue的博客网站(由0开始)-----第七天 学习Shiro的一天

 

参考了markerHub的开源项目,大家可以去看一下,我觉得整个开发过程很完整。

基本上也是参照开源项目写的,这个部分我不是很熟悉,即使我看完了理论教程,也不是很能写出来,所以就模仿下写了。

shrio+jwt参考视频

第一步:在pom文件导入shiro-redis的starter包:还有jwt的工具包,简化开发,引入hutool工具包。

Hutool的存在就是为了减少代码搜索成本,避免网络上参差不齐的代码出现导致的bug。


    org.crazycake
    shiro-redis-spring-boot-starter
    3.2.1



    cn.hutool
    hutool-all
    5.3.3



    io.jsonwebtoken
    jjwt
    0.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(List realms, 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();
        Map filterMap = 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();
        Map filterMap = 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: 属实是记得写时间在写上去。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5583319.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存