Spring集成Shiro使用小结
shiro的认证流程
Application Code:应用程序代码,由开发人员负责开发的
Subject:框架提供的接口,代表当前用户对象
SecurityManager:框架提供的接口,代表安全管理器对象
Realm:可以开发人员编写,框架也提供一些,类似于DAO层,用于访问权限数据
引入maven依赖
   <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-all -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-all</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring -->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.4.0</version>
        </dependency>
配置web.xml
    <!-- 配置Spring框架提供的用于整合Shiro框架的过滤器   shiro 过滤器一定要保证 要先进入!!
        这个过滤器的名字必须与Spring配置文件中的ben配置id相同
    -->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>shiroFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
在Spring配置文件中配置shiro
    <!--shiro 配置方式-->
    <!--注册realm-->
    <bean id="myRealm" class="top.wintp.crud.service.MyRealm"/>
    <!--配置安全管理器-->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="myRealm"/>
    </bean>
    <!--配置shiro过滤器工厂对象-->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!--securityManager 注入安全管理器-->
        <property name="securityManager" ref="securityManager"/>
        <!--注入相关页面的访问URL-->
        <property name="loginUrl" value="/user/login.do"/>
        <!--<property name="successUrl"/>-->
        <property name="unauthorizedUrl" value="/user/unAuth.do"/>
        <!--
            注入URL拦截规则
        -->
        <property name="filterChainDefinitions">
            <value>
                /static/** = anon
                /user/login.do=anon
                /user/loginUser.do=anon
                /emp/findAll.do=perms["admin"]
                /** = authc
            </value>
        </property>
    </bean>
MyRealm
package top.wintp.crud.service;
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.realm.AuthorizingRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import top.wintp.crud.dao.TUserMapper;
import top.wintp.crud.entity.TUser;
import top.wintp.crud.entity.TUserExample;
/**
 * 类描述:
 * <p>
 * 作者:  pyfysf
 * <p>
 * qq:  337081267
 * <p>
 * CSDN:    http://blog.csdn.net/pyfysf
 * <p>
 * 个人博客:    http://wintp.top
 * <p>
 * 邮箱:  pyfysf@163.com
 * <p>
 * 时间:2018/8/22
 */
public class MyRealm extends AuthorizingRealm {
    @Autowired
    private TUserMapper mTUserMapper;
    @Override
    protected AuthorizationInfo
    doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("自定义realm授权方法");
    @Override
    protected AuthorizationInfo
    doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("自定义realm授权方法");
        TUser user = (TUser) principalCollection.getPrimaryPrincipal();
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addStringPermission("admin");
        //授权
        return authorizationInfo;
    }
    @Override
    protected AuthenticationInfo
    doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("自定义realm认证方法");
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        TUserExample tUserExample = new TUserExample();
        tUserExample.createCriteria().andUsernameEqualTo(token.getUsername());
        List<TUser> tUsers = mTUserMapper.selectByExample(tUserExample);
        if (tUsers != null && tUsers.size() > 0) {
            TUser tUser = tUsers.get(0);
            //简单认证信息对象
            AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(tUser, tUser.getPassword(), this.getName());
            //认证
            return authenticationInfo;
        } else {
            return null;
        }
    }
}
修改用户登录的方法
@Service
public class UserService {
    public boolean loginUser(TUser user) {
        String username = user.getUsername();
        //shiro执行过程  获取当前用户--subject -->然后获取securityManager(安全管理器)(login 登录)
        // 然后调用realm
        //获取当前用户对象 -- 未认证
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token
                = new UsernamePasswordToken(user.getUsername(), user.getPassword());
        try {
            subject.login(token);
            TUser resultUer = (TUser) subject.getPrincipal();
            System.out.println("登录成功");
            return true;
        } catch (Exception e) {
        //代表认证失败
            e.printStackTrace();
            return false;
        }
    }
}
常用过滤器配置简称
注解式编程
首先需要在Spring的配置文件中开启Shiro的注解支持:在applicationContext.xml中加入下面代码:
    <!--开启shiro 框架的注解支持-->
    <bean id="advisorAutoProxyCreator"
          class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
        <!--默认开启CGLIB代理-->
        <property name="proxyTargetClass" value="true"/>
    </bean>
    <!--配置切面  用于创建代理对象-->
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/>
有了上面的配置,我们就可以在我们的代码中使用Shiro的注解进行权限控制了:
    @RequestMapping("/findAll")
   @RequiresPermissions("emp-check")
    public String findAll(Model model, @RequestParam(value = "pageNum", defaultValue = "1")
            Integer pageNum) {
        logger.info("请求开始>>>>>");
        //书写分页逻辑--在这里进行分页声明之后,后面紧跟的查询就是一个分页目标
        //第二个参数是指定每次查询几条数据
        PageHelper.startPage(pageNum, 5);
        //调用Service里面的方法进行使用
        List<Employee> allEmployees = mEmployeeService.findAll();
        //使用PageInfo来包装返回的数据--可以更好的管理分页逻辑
        //第二个参数是页面上最多显示几个页数,比如限制只显示5个那么就为1,2,3,4,5
        //2,3,4,5,6||||3,4,5,6,7
        PageInfo<Employee> employeePageInfo = new PageInfo<Employee>(allEmployees, 5);
        logger.info("数据为:" + employeePageInfo);
        logger.info("请求结束>>>>>");
        //存储数据,跳转界面
        model.addAttribute("employeePageInfo", employeePageInfo);
        return "list";
    }
中途遇到的问题
配置注解之后,没有起到任何作用。 
可能一:在你的spring的配置文件中忽略扫描Controller注解,然而你在Controller中使用了@RequiresPermissions,那么我们需要把上面注解支持的代码配置到Spring-mvc.xml文件中。
    <!--扫描所有包-->
    <context:component-scan base-package="top.wintp.crud">
        <!--除了控制器 都进行注解扫描-->
        <context:exclude-filter type="annotation"
                                expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
如果有上面的配置,那么spring将不会扫描到Controller注解
可能二:在你的spring-mvc中仅仅只是扫描到了Controller注解,然而你在service层或者dao层用到了@RequiresPermissions,那么我们需要把上面注解支持的代码配置到applicationContext.xml文件中。
  <context:component-scan base-package="top.wintp.crud" use-default-filters="false">
        <!--只扫描控制器即可-->
        <context:include-filter type="annotation"
                                expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
建议:在Spring的主配置文件中和Springmvc的配置文件中都加入对shiro注解的支持。特别注意:如果两个配置文件中都配置了,注意其id不能相同
在jsp中使用shiro提供的标签库
一、引入标签库
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
二、使用合适的标签在合适的位置进行使用
例如:
<shiro:hasPermission name="admin">
    <button class="btn btn-primary" id="btn_add_emp">新增</button>
    <button class="btn btn-danger btn_all_del">删除</button>
</shiro:hasPermission>
上述代码为,当当前用户具有admin的权限时,新增和删除按钮才会显示
Spring集成Shiro使用小结的更多相关文章
- Spring集成shiro做登陆认证
		
一.背景 其实很早的时候,就在项目中有使用到shiro做登陆认证,直到今天才又想起来这茬,自己抽空搭了一个spring+springmvc+mybatis和shiro进行集成的种子项目,当然里面还有很 ...
 - spring集成shiro报错解决(no bean named 'shiroFilter' is defined)
		
引言: 本人在使用spring集成shiro是总是报“no bean named 'shiroFilter' is defined”,网上的所有方式挨个试了一遍,又检查了一遍, 还是没有解决,最后,抱 ...
 - shiro实战系列(十五)之Spring集成Shiro
		
Shiro 的 JavaBean 兼容性使得它非常适合通过 Spring XML 或其他基于 Spring 的配置机制.Shiro 应用程序需要一个具 有单例 SecurityManager 实例的应 ...
 - spring 集成shiro 之 自定义过滤器
		
在web.xml中加入 <!-- 过期时间配置 --> <session-config><session-timeout>3</session-timeout ...
 - Shiro学习总结(10)——Spring集成Shiro
		
1.引入Shiro的Maven依赖 [html] view plain copy <!-- Spring 整合Shiro需要的依赖 --> <dependency> <g ...
 - spring集成shiro登陆流程(下)
		
首先声明入门看的张开涛大神的<跟我学shiro> 示例:https://github.com/zhangkaitao/shiro-example 博客:http://jinnianshil ...
 - spring集成shiro登陆流程(上)
		
上一篇已经分析了shiro的入口filter是SpringShiroFilter, 那么它的doFilter在哪儿呢? 我们看到它的直接父类AbstractShrioFilter继承了OncePerR ...
 - Spring集成shiro+nginx  实现访问记录
		
最近公司的网站需要添加用户访问记录功能,由于使用了nginx请求转发直接通过HttpServletRequest无法获取用户真实Ip 关于nginx获取真实IP的资料 https://blog.cs ...
 - spring集成shiro,事务失效问题 not eligible for auto-proxying
		
BeanPostProcessor bean实例化顺序有关,@Configuration会最先实例化,也就是在spring启动完成之前. 导致Configuration中使用的注入,没能在spring ...
 
随机推荐
- 深入了解Windows句柄到底是什么(句柄是逻辑指针,或者是指向结构体的指针,图文并茂,非常清楚)good
			
总是有新入门的Windows程序员问我Windows的句柄到底是什么,我说你把它看做一种类似指针的标识就行了,但是显然这一答案不能让他们满意,然后我说去问问度娘吧,他们说不行网上的说法太多还难以理解. ...
 - c#编写的基于Socket的异步通信系统--SanNiuSignal.DLL已开源
			
自从推出了SanNiuSignal.DLL,用户反映还是满好的;为了更好的服务于大家,我已经修复了很多BUG,同时把这个DLL开源;下面就先来介绍下 使用这个DLL开发出的简单的通信系统;如图: 想使 ...
 - 梭子鱼VS多备份 虽殊途却同归
			
备份,对于企业来说,不仅是一个已经拥有多年历史的传统IT工作,还关系着企业自身的生死存亡.在云计算时代下,备份业务成为企业的必选项,已经成为云计算服务最为热门的领域之一.基于云的备份正在深刻改变着备份 ...
 - 快速开发平台  WebBuilder 8 发布
			
快速开发平台 WebBuilder 8 发布 了解:http://www.putdb.com,官网:http://www.geejing.com 什么是WebBuilder? WebBuilder是 ...
 - 当程序调用dll时获取dll路径,DLL中获取自身的句柄
			
当程序调用dll时,获取dll路径的方法: HMODULE hMod = GetModuleHandle(_T("axload.dll")); if (hMod != NULL) ...
 - MAC和PHY的区别(网线上传递的是模拟信号)
			
一块以太网网卡包括OSI(开方系统互联)模型的两个层.物理层和数据链路层.物理层定义了数据传送与接收所需要的电与光信号.线路状态.时钟基准.数据编码和电路等,并向数据链路层设备提供标准接口.数据链路层 ...
 - Navicat for MySQ v11-v12都有的,供大家学习提升使用
			
Navicat for MySQL破解版是一套专为 MySQL 设计的高性能数据库管理及开发工具,Navicat for MySQL破解版主要功能包括SQL创建工具或编辑器.数据模型工具.数据传输.导 ...
 - MapReduce in MongoDB
			
MongoDB の MapReduce 在Hadoop的学习中已经接触过MapReduce了,它是一个很成熟的计算模型,将大批量的工作(也就是数据)分解(MAP映射)执行,最后将结果合并成最终的Red ...
 - Python 3网络爬虫开发实战中文PDF+源代码+书籍软件包(免费赠送)+崔庆才
			
Python 3网络爬虫开发实战中文PDF+源代码+书籍软件包+崔庆才 下载: 链接:https://pan.baidu.com/s/1H-VrvrT7wE9-CW2Dy2p0qA 提取码:35go ...
 - 阿里云服务器CentOS7.5安装RabbitMQ
			
RabbitMQ是实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件).RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的. 为什么 ...