2521-Shiro系列-基本使用

Posted starmoon1994

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2521-Shiro系列-基本使用相关的知识,希望对你有一定的参考价值。

在springboot中使用SHiro作为安全框架,非常简单,灵活性也比较高

在springboot中使用Shiro不用像官网教程那样,官网是将配置文件写在INI文件和XML配置中

springboot中提倡使用javaconfig的形式,所以这里都采用javaconfig的形式。

记录Shiro的初步使用(配置登录接口,认证成功的处理、认证失败的处理、无认证信息的处理)
进阶使用(使用缓存管理Shiro的Session和Cache)
完整版使用 (给出可在生产中使用的配置)

初步使用

  1. 自定义MyAuthorizingRealm类,继承类AuthorizingRealm,实现里面的doGetAuthorizationInfo和doGetAuthenticationInfo方法

AuthorizingRealm是Shiro提供的处理认证授权的抽象类,oGetAuthenticationInfo就是认证的处理,doGetAuthorizationInfo就是授权的处理。功能非常丰富。

  1. 自定义一个ShiroConfig类,对Shiro进行配置,主要是配置ShiroFilterFactoryBean,SecurityManager,DefaultWebSessionManager,AuthorizationAttributeSourceAdvisor

ShiroFilterFactoryBean,主要是配置某个Url的权限情况
DefaultWebSessionManager:对session进行管理,如命名、有效期等此处的Session是经过Shiro封装的session,扩展了相关属性。
AuthorizationAttributeSourceAdvisor:配置基于aop形式的授权校验,可在接口上通过注解添加权限处理

  1. 编写登录接口
    使用Shiro提供的Subject对象,调用其login方法,即可完成登录。

登录时会调用之前在MyAuthorizingRealm类定义的doGetAuthenticationInfo的认证逻辑(获取身份信息、密码加盐加密等),这其中还会涉及一些缓存的操作,暂时按下不表。

如何自定义Shiro的Filter?

Shiro已经提供了很多实现好的过滤器,可参考org.apache.shiro.web.filter.mgt.DefaultFilter枚举类,里面有实现类和简写的映射关系。

常用的如 anon(AnonymousFilter.class),authc(FormAuthenticationFilter.class),logout(LogoutFilter.class)等。

实现:

  1. 自定义类CustomFormAuthenticationFilter extends FormAuthenticationFilter
  2. 注册CustomFormAuthenticationFilter到shiroFilterFactoryBean中

tips:CustomFormAuthenticationFilter在获取时,只能用构造器new出来,spring容器中无法自定注入该类

参考:

    /**
     * 在此配置拦截器栈
     */
    @Bean
    public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
        System.out.println("init ShiroConfiguration.shirFilter()");


        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        //注册自定义filter 命名为authc 覆盖默认FormAuthenticationFilter
        Map<String, Filter> filterMap = shiroFilterFactoryBean.getFilters();
        filterMap.put("authc2", new CustomFormAuthenticationFilter());
        shiroFilterFactoryBean.setFilters(filterMap);

        //拦截器.
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
        // 配置不会被拦截的链接 顺序判断 注意过滤器配置顺序 不能颠倒
        //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了,登出后跳转配置的loginUrl
        filterChainDefinitionMap.put("/logout.do", "logout");
        // 配置不会被拦截的链接 顺序判断
        filterChainDefinitionMap.put("/druid/**", "anon");
        filterChainDefinitionMap.put("/static/**", "anon");
        // ajax方式的登录
        filterChainDefinitionMap.put("/ajaxLogin.do", "anon");
        // ajax方式的退出登录
        filterChainDefinitionMap.put("/ajaxLogout.do", "anon");
        filterChainDefinitionMap.put("/unauth.do", "anon");
        filterChainDefinitionMap.put("/formLogin.do", "authc2");
        filterChainDefinitionMap.put("/**", "authc");
        // 表单登录地址 是指跳转到登录页的url 而不是指定登录接口
        shiroFilterFactoryBean.setLoginUrl("/formLogin.do");
        // 表单登录成功后的跳转地址
        shiroFilterFactoryBean.setSuccessUrl("/loginSuccess.do");
        // 请求未认证的跳转地址
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauth.do");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }

如何进行传统表单登录而不是ajax形式?

在config类中配置一个接口,并用authc(FormAuthenticationFilter.class)过滤器进行认证,即可走表单登录。

地雷

  1. ShiroFilterFactoryBean配置的地址坑很多
shiroFilterFactoryBean.setLoginUrl("/formLogin.do");
// 表单登录成功后的跳转地址
shiroFilterFactoryBean.setSuccessUrl("/loginSuccess.do");
// 请求未认证的跳转地址
shiroFilterFactoryBean.setUnauthorizedUrl("/unauth.do");

LoginUrl配置的地址,是表单登录接口,但如果已经登录成功,再访问该接口重新登录,shiro并不会拦截到该接口,而是直接放行。springMVC会直接去寻找/formLogin.do接口,如果没有自定义该接口,就会报404

SuccessUrl是authc(FormAuthenticationFilter.class)处理登录成功后的跳转地址

UnauthorizedUrl是请求认证时发现无认证信息时,跳转的接口

  1. 配置可参考org.apache.shiro.spring.web.config包下的AbstractShiroWebConfiguration类,有一些参数配置文件的读取

代码参考地址

https://github.com/starmoon1994/shiro-collection




以上是关于2521-Shiro系列-基本使用的主要内容,如果未能解决你的问题,请参考以下文章

最全最详细publiccms常用的代码片段

最全最详细publiccms其他常用代码片段(内容站点)

Kotlin基础从入门到进阶系列讲解(基础篇)Fragment的基本使用

Kotlin基础从入门到进阶系列讲解(基础篇)Fragment的基本使用

c_cpp Robolution基本代码片段

SpringCloud系列十一:SpringCloudStream(SpringCloudStream 简介创建消息生产者创建消息消费者自定义消息通道分组与持久化设置 RoutingKey)(代码片段