Shiro (包含权限满足其中一个就通过的用法)
方法/步骤
- 1
web.xml添加配置
<!-- shiro过滤器 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 2
shiro与spring整合配置
<!-- 使用shiro安全检查注解 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor" />
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
<!-- shiro的生命周期处理器 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
<!-- shiro自带的密码匹配器(用来校验密码足够了) -->
<bean id="credentialsMatcher" class="org.apache.shiro.authc.credential.SimpleCredentialsMatcher"></bean>
<!-- security datasource: -->
<bean id="myRealm" class="cc.eguid.service.shiro.MyRealm">
<property name="credentialsMatcher" ref="credentialsMatcher"/><!-- 密码匹配器 -->
<property name="cachingEnabled" value="false"/><!-- 禁止缓存 -->
</bean>
<!-- 安全管理器 -->
<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">
<!-- 配置安全管理器 -->
<property name="securityManager" ref="securityManager" />
<!-- 身份认证失败跳转的地址 -->
<property name="loginUrl" value="/login/" />
<!-- 身份认证成功跳转的地址 -->
<property name="successUrl" value="/" />
<!-- 权限认证失败跳转的地址 -->
<property name="unauthorizedUrl" value="/login/unauthorized" />
<property name="filterChainDefinitions">
<!--anon 表示匿名访问,不需要认证以及授权 -->
<!--authc表示需要认证 没有进行身份认证是不能进行访问的 -->
<!--authc,roles[admin]表示是admin角色的用户才能访问 -->
<value>
/static/** = anon
/login/** = anon
/common/** = anon
/admin/** = authc,roles[admin]
/* = authc
/** = authc
</value>
</property>
</bean>
- 3
realm和自定义密码校验器实现
public class MyRealm extends AuthorizingRealm{
Logger log=Logger.getLogger(MyRealm.class);
@Autowired
private UserService userService;//这是自己实现的用户信息操作类,实现用户信息,用户角色信息、用户权限信息查询功能
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
UserInfo user = (UserInfo) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 查询角色信息
Collection<String> roles = userService.findRoles(user);
info.addRoles(roles);
log.info("shiro获取用户所属角色列表:"+roles);
// 查询权限信息
Collection<String> permissions = userService.findPermissions(user.getSystemuserid());
info.addStringPermissions(permissions);
log.info("shiro获取用户权限列表:"+permissions);
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)throws AuthenticationException{
//用户输入的用户名密码
String loginname= token.getPrincipal().toString();
Object password=token.getCredentials();
log.info("shiro正在处理尝试登录的用户信息:"+loginname+",密码:"+new String((char[])password));
//数据库中的用户信息
UserInfo user =userService.queryUserInfoByLoginName(loginname);
if(user==null||CommonUtil.isNull(user.getLoginusername(),user.getPassword(),user.getSystemuserid())){
return null;
}
log.info("shiro获取到当前用户尝试登录的真实数据:"+user.getLoginusername()+",密码:"+user.getPassword());
//数据库中的正确的账户信息
AuthenticationInfo accountInfo =new SimpleAuthenticationInfo(user, user.getPassword(),getName());
//自己获取密码验证器(由于shiro实现的密码校验方法是密码错误会直接抛异常,不采用,所以改成直接手动校验)
CredentialsMatcher matcher=getCredentialsMatcher();
if(matcher==null){
log.error("没有配置密码匹配器");
return null;
}
//校验密码
if(matcher.doCredentialsMatch(token,accountInfo)){
return accountInfo;//校验通过,返回账号信息
}
return null;
}
}
- 4
自定义密码校验器
/**
* 自定义shiro密码匹配(密码是在md5散列值的基础上再次进行md5加盐操作,加盐值不保存在数据库,而是放在配置文件中)
* @author eguid
*
*/
public class MyCredentialsMatcher extends CodecSupport implements CredentialsMatcher {
private static final Logger log = LoggerFactory.getLogger(MyCredentialsMatcher.class);
protected Object getCredentials(AuthenticationToken token) {
return token.getCredentials();
}
protected Object getCredentials(AuthenticationInfo info) {
return info.getCredentials();
}
@Autowired
private CommonConfigs commonConfigs;
/**
* 验证密码
*
* @param tokenCredentials
* @param accountCredentials
* @return
*/
protected boolean equals(Object tokenCredentials, Object accountCredentials) {
if (log.isDebugEnabled()) {
log.debug("Performing credentials equality check for tokenCredentials of type ["
+ tokenCredentials.getClass().getName() + " and accountCredentials of type ["
+ accountCredentials.getClass().getName() + "]");
}
if (isByteSource(tokenCredentials) && isByteSource(accountCredentials)) {
if (log.isDebugEnabled()) {
log.debug("Both credentials arguments can be easily converted to byte arrays. Performing "
+ "array equals comparison");
}
byte[] tokenBytes = toBytes(tokenCredentials);
byte[] accountBytes = toBytes(accountCredentials);
return MessageDigest.isEqual(tokenBytes, accountBytes);
} else {
return accountCredentials.equals(tokenCredentials);
}
}
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
Object tokenCredentials = getCredentials(token);
Object accountCredentials = getCredentials(info);
String account=String.valueOf((char[])tokenCredentials);
if(commonConfigs.getMd5salt()==null){
if (log.isDebugEnabled()) {
log.debug("配置文件中的加盐值为空,无法进行密码匹配,请确认配置文件是否在指定位置或配置指定加盐值");
}
return false;
}
String saltaccount=MD5Util.getMD5(account, commonConfigs.getMd5salt());
if (log.isDebugEnabled()) {
log.debug("加盐后的密码:"+saltaccount);
}
return equals(accountCredentials, saltaccount.toCharArray());
}
}
- 5
注解使用及模板标签使用
1、注解使用
@RequiresPermissions({"user:update:view"})//检查操作权限
@RequiresPermissions(value={"user:add","user:view"},logical=Logical.OR)//两个操作权限其中一个满足条件即可通过检查
@RequiresRoles({"admin"})//检查角色
@RequiresRoles(value={"debug","admin"},logical=Logical.OR)//两个角色其中一个角色满足条件即可@RequiresAuthentication//检查是否通过shiro认证
@RequiresGuest//不需要验证
@RequiresUser//检查用户是否是当前系统中的用户2、标签使用
使用标签需要先导入shiro的标签库<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
(1)显示用户身份信息
<shiro: principal/>
默认调用Subject.getPrincipal()获取<shiro:principal property="username"/>
相当于((User)Subject.getPrincipals()).getUsername()(2)已登录shiro用户显示
<shiro:user>
欢迎[<shiro:principal/>]登录,<a href="logout">退出</a>
<shiro:user>(3)匿名用户访问
<shiro:guest>未经过shiro验证的用户(游客,匿名用户)</shiro:guest>(4)已经在shiro登录过的(已登录用户)
<shiro:authenticated>
用户[<shiro:principal/>]已身份验证通过
<shiro:authenticated>(5)没有在shiro登录过的
<shiro:notAuthenticated>
未身份验证(包括记住我)
<shiro:notAuthenticated>(6)检查角色
<shiro:hasRole name="admin">
用户[<shiro:principal/>]拥有角色admin<br/>
<shiro:hasRole>检查任意角色(其中一个满足条件即通过,相当于OR)
<shiro:hasAnyRoles name="admin,user">
用户[<shiro:principal/>]拥有角色admin或user<br/>
<shiro:hasAnyRoles>不具有角色(反向判断)
<shiro:lacksRole name="abc">
用户[<shiro:principal/>]不具有角色abc<br/>
<shiro:lacksRole>(7)操作权限判断
<shiro:hasPermission name="user:create">
用户[<shiro:principal/>]拥有权限user:create<br/>
<shiro:hasPermission>不具有操作权限(反向判断)
<shiro:lacksPermission name="org:create">
用户[<shiro:principal/>]没有权限org:create<br/>
<iro:lacksPermission>END
Shiro (包含权限满足其中一个就通过的用法)的更多相关文章
- Apache Shiro 开源权限框架
在 Web 项目中应用 Apache Shiro 开源权限框架 Apache Shiro 是功能强大并且容易集成的开源权限框架,它能够完成认证.授权.加密.会话管理等功能.认证和授权为权限控制的核心, ...
- springBoot2.0 配置shiro实现权限管理
一.前言 基于上一篇springBoot2.0 配置 mybatis+mybatisPlus+redis 这一篇加入shiro实现权限管理 二.shiro介绍 2.1 功能特点 Shiro 包含 10 ...
- Shiro权限管理框架(三):Shiro中权限过滤器的初始化流程和实现原理
本篇是Shiro系列第三篇,Shiro中的过滤器初始化流程和实现原理.Shiro基于URL的权限控制是通过Filter实现的,本篇从我们注入的ShiroFilterFactoryBean开始入手,翻看 ...
- SpringBoot与Shiro整合权限管理实战
SpringBoot与Shiro整合权限管理实战 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] *观看本文章需要有一定SpringBoot整合经验* Shiro框架简介 Apach ...
- Dubbo学习系列之九(Shiro+JWT权限管理)
村长让小王给村里各系统来一套SSO方案做整合,隔壁的陈家村流行使用Session+认证中心方法,但小王想尝试点新鲜的,于是想到了JWT方案,那JWT是啥呢?JavaWebToken简称JWT,就是一个 ...
- shiro入门笔记之第一个demo创建
前言 看到这篇文章之前,可能很多小伙伴都没听过shiro,那么shiro是什么呢?shiro是Apache基金会下一个非常有名的开源项目(项目官网: http://shiro.apache.org/ ...
- SpringBoot&Shiro实现权限管理
SpringBoot&Shiro实现权限管理 引言 相信大家前来看这篇文章的时候,是有SpringBoot和Shiro基础的,所以本文只介绍整合的步骤,如果哪里写的不好,恳请大家能指出错误,谢 ...
- 【shiro】(5)---基于Shiro的权限管理
基于Shiro的权限管理项目搭建 前面写了四篇有关权限的文章,算是这篇文章的铺垫了.这篇文章采用 开发环境 JDK1.8 Eclipse Mav ...
- 关于 Shiro 的权限匹配器和过滤器
项目源码:https://github.com/weimingge14/Shiro-project演示地址:http://liweiblog.duapp.com/Shiro-project/login ...
随机推荐
- HNUSTOJ-1617 Graph(费马数)
1617: Graph 时间限制: 1 Sec 内存限制: 32 MB提交: 31 解决: 5[提交][状态][讨论版] 题目描述 Your task is to judge whether a ...
- Linux虚拟机常用命令
参考原文链接:(https://blog.csdn.net/fanyun_01/article/details/51083585) 一.Linux虚拟机常用命令 # virsh list //查看已打 ...
- go 结构体2 文法
结构体文法表示通过结构体字段的值作为列表来新分配一个结构体. 使用 Name: 语法可以仅列出部分字段.(字段名的顺序无关.) 特殊的前缀 & 返回一个指向结构体的指针. //分配的v1结构体 ...
- Kubernetes 学习笔记(五):数据卷
"数据卷"通常和"有状态"这个词同时出现,卷用于给有状态应用保存/共享状态. 常用的数据卷类型 1. emptyDir: 用于存储临时数据的空目录 emptyD ...
- 区间第k大问题 权值线段树 hdu 5249
先说下权值线段树的概念吧 权值平均树 就是指区间维护值为这个区间内点出现次数和的线段树 用这个加权线段树 解决第k大问题就很方便了 int query(int l,int r,int rt,int k ...
- 轻松搭建CAS 5.x系列(8)-在CAS Server增加双因素认证(DUO版)
概述说明 为了让系统更加安全,很多登录会加入双因素认证.何为双因素,如果把登陆作为开一扇门的话,那就是在原来的锁上再加一把锁,第二锁用新的钥匙,这样安全系数就更加高了. CAS是通过账号名和密码来认证 ...
- [JZOJ5465]道路重建--边双缩点+树的直径
题目链接 lueluelue 分析 这鬼题卡了我10发提交,之前做过一道类似的题目:https://rye-catcher.github.io/2018/07/09/luogu%E9%A2%98%E8 ...
- windows找不到头文件的问题
windows系统中,设置好了环境变量,就可以在cmd下直接执行文件,但是 特别是在c语言或者c++程序中,include头文件的问题,如果找不到,就考虑是不是文件放错地方了. windows上编译c ...
- SAP UI5应用入口App.controller.js是如何被UI5框架加载的?
首先在UI5应用的manifes.json里,定义了UI5应用的入口视图为App: 调试器里的pending数组的两个元素: 实际上对应了我在App.controller.js里定义的两个依赖: 而a ...
- C#基础 类及常用函数【string 、Math 、DiteTime 、TimeSpan】
一 string 类型 string str = "abcdefg"; str.Length - 字符串长度,返回int类型 str.TrimStart() ...