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 ...
随机推荐
- 程序员该如何过好他的整个职业生涯?(最重要的是你得一直往前走。拐点不是你的工资。想起很久前有个人说我“逻辑性”比较强)good
作者|池建强 编辑|小智 戳阅读原文,获得短信提醒,不错过下次InfoQ大咖说直播! 1 写在前面 加入极客邦的第一天就被拉到了「大咖说」的现场,这也是我始料未及的事情.从锤子科技正式离职之后,我 ...
- 以太坊(ethereum)开发DApp应用的入门区块链技术教程
概述 对初学者,首先要了解以太坊开发相关的基本概念. 学习以太坊开发的一般前序知识要求,最好对以下技术已经有一些基本了解: 一种面向对象的开发语言,例如:Python,Ruby,Java... 前 ...
- MFC 中 Tooltip 实现的几种方式
方法一:利用CWnd本身自身支持的tooptip来实现,这种方法适用给控件增加tooltip,非常方便和简单方法如下:1.在窗口中增加消息映射ON_NOTIFY_EX(TTN_NEEDTEXT, 0, ...
- Boyer-Moore字符串查找算法的实现
前段时间在园子里看到一篇讲Boyer-Moore算法原理的文章http://kb.cnblogs.com/page/176945/,写的很详细,于是在这里自己写个C语言的实现,权当是练手吧. 基本思路 ...
- 使用Arcgis Api for Javascript 调用 本地Portal发布的WebMap
1.环境搭建 安装Arcgis Portal 10.4,Server 10.4,DataStore ,WebAdaptor for IIS,搭建arcgis api for javascript 4. ...
- Java 函数传入参数后,究竟发生了什么?java函数传参数原理解析
JAVA函数在传入参数A时,会在函数作用周期内生成一个与参数相同类型的局部变量B. B与A指向同一块内存区域,并且具有相同的名字如param. 在函数内所有对param的操作都是对B的操作.对B进行赋 ...
- hive表批处理
对hive中的表进行批量处理,如下是一个简单的脚本 #给定一个hive数据库名,生成它的所有表的create SQL语句,并导出到文件 create_fun(){ hive -e } #显示一个表中所 ...
- springboot读取本地项目文件
在读取springBoot+gradle构建的项目时,如果使用传统的FileInputStream读取文件流或者ResourceUtils工具类的方式 File file= ResourceUtils ...
- spring 5.x 系列第1篇 —— springmvc基础 (xml配置方式)
文章目录 一.搭建hello spring工程 1.1 项目搭建 1.2 相关配置讲解 二.配置自定义拦截器 三.全局异常处理 四.参数绑定 4.1 参数绑定 4.2 关于日期格式转换的三种方法 五. ...
- docker search/pull 报错
docker报错 Get https://registry-1.docker.io/v2/: x509: certificate has expired or is not yet valid 这种错 ...