Shiro入门之一 -------- Shiro权限认证与授权
一 将Shirojar包导入web项目
二 在web.xml中配置shiro代理过滤器
注意: 该过滤器需要配置在struts2过滤器之前
<!-- 配置Shiro的代理过滤器 -->
<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的配置文件applicationContext.xml中配置Shiro的过滤器
注意:过滤器ShiroFilterFactoryBean的id必须与web.xm中的过滤器name属性值一致
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 注入shiro的安全管理员 -->
<property name="securityManager" ref="securityManager"></property>
<!--
注入登录路径
loginUrl :没有登录的用户请求需要登录的页面时自动跳转到登录页面,不是必须的属性,
不输入地址的话会自动寻找项目web项目的根目录下的”/login.jsp”页面。
-->
<property name="loginUrl" value="/login.jsp"></property>
<!--
注入登录成功的路径
successUrl :登录成功默认跳转页面,不配置则跳转至”/”。如果登陆前点击的一个需要登录的页面,
则在登录自动跳转到那个需要登录的页面。不跳转到此。
-->
<property name="successUrl" value="/index.jsp"></property>
<!--
注入权限不足的路径
unauthorizedUrl :没有权限默认跳转的页面。
-->
<property name="unauthorizedUrl" value="/unauthorizedUrl.jsp"></property>
<!-- url权限级别的控制 -->
<property name="FilterChainDefinitions">
<value>
<!-- 对页面应用的css文件放行 anon表示不需要任何权限就能访问 -->
/css/** = anon
<!-- 对页面应用的js文件放行 -->
/js/** = anon
<!-- 对页面应用的图片images文件放行 -->
/images/** = anon
<!-- 对页面应用的验证码jsp文件,jsp后面加*号是在验证码jsp后面跟参数也放行 -->
/validatecode.jsp* = anon
<!-- 对页面应用的登录页面放行 -->
/login.jsp* = anon
<!-- 对页面应用的登录提交的login.action类放行 -->
/user_login* = anon
<!-- 对访问staff.action设置权限限制 -->
/page_base_staff.action = perms[staff]
<!-- 对其他上面没有设置的路径设置权限设置 -->
<!-- 过滤器链的执行顺序是自上而下依次匹配, 如果能匹配上, 则不再往下匹配 -->
/** = authc
</value>
</property>
</bean>
四 在登录方法中,编写Shiro相关的代码
//登录功能
public String login () {
HttpServletRequest request = ServletActionContext.getRequest();
//1.验证码校验
String validateCode = (String) request.getSession().getAttribute("key");
if (StringUtils.containsWhitespace(checkcode) || !validateCode.equalsIgnoreCase(checkcode)) {
//1.1如果校验不成功,跳转到登录页面,并提示"验证码不正确的信息"
this.addActionError(this.getText("checkCodeError"));
return "login";
}
//2.如果校验成功实现登录功能
//创建subject权限对象
//Subject 是与程序进行交互的对象,可以是人也可以是服务或者其他,通常就理解为用户。
//所有Subject 实例都必须绑定到一个SecurityManager上。我们与一个 Subject 交互,
//运行时shiro会自动转化为与 SecurityManager交互的特定 subject的交互。
Subject subject = SecurityUtils.getSubject();
//创建用户名和密码的令牌
String username = model.getUsername();
String password = model.getPassword();
password = MD5Utils.md5(password);
AuthenticationToken token = new UsernamePasswordToken(username, password);
//调用安全管理器
try {
subject.login(token);
//从subject中获取保存在安全管理员中的user对象
User user = (User) subject.getPrincipal();
//将用户保存在session中,因为自定义拦截器的原因(如果没有自定义拦截器, 将用户存放在session域中的这个步骤可以省略)
request.getSession().setAttribute("loginUser", user);
} catch (UnknownAccountException e) {
e.printStackTrace();
this.addActionError(this.getText("usernameError"));
return "login";
} catch (AuthenticationException e) {
e.printStackTrace();
this.addActionError(this.getText("passwordError"));
return "login";
}
return "home";
}
五 创建Realm安全数据桥, 通过继承AuthorizingRealm的方式实现
public class BOSRealm extends AuthorizingRealm {
@Resource
private IUserDao userDao;
//权限认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken paramAuthenticationToken)
throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) paramAuthenticationToken;
String username = token.getUsername();
//调用userdao根据用户名查询用户
User user = userDao.findByUsername(username);
if (user != null) {
//如果查询的用户存在
//TODO 与数据库中用户名和密码进行比对。比对成功则返回info,比对失败则抛出对应信息的异常AuthenticationException
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user,
user.getPassword(), this.getClass().getName());
return authenticationInfo;
} else {
//如果查询不到用户, 返回空, Shiro会抛出UnknownAccountException异常
return null;
}
}
//授予权限
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection paramPrincipalCollection) {
// TODO Auto-generated method stub
return null;
}
}
六 在Spring配置文件applicationContext.xml中配置Shiro安全管理器
<!-- 7配置Shiro的安全管理器 -->
<bean name="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<!-- 注入realm数据桥 -->
<property name="realm" ref="bosRealm"></property>
</bean>
<!-- 配置Realm数据桥对象 -->
<bean id="bosRealm" class="cn.rodge.bos.shiro.BOSRealm"></bean>
七 在自定义Realm中, 为当前用户授权
在Shiro权限认证之后, 认证过的用户对于特定权限的页面或者功能仍然不具备访问权限, 此时就需要针对不同的用户进行相应的授权操作. Shiro的授权操作是在权限认证的基础之上完成的. 需要修改BOSRealm类中的权限授予的方法.
//授予权限
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection paramPrincipalCollection) {
//创建授权信息对象
SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
//根据当前用户查询数据库,获取其权限对象
//获取当前用户,由于shiro的过滤器在struts的过滤器之前执行,因此此时的用户还没有被封装到session中,
//故获取当前用户在session中娶不到
/*Subject subject = SecurityUtils.getSubject();
User loginUser = (User) subject.getPrincipal();*/
User loginUser = (User) paramPrincipalCollection.getPrimaryPrincipal();
if (loginUser != null) {
List<Function> list = null;
//表示用户存在,调用roledao根据用户查询所有权限
if ("admin".equals(loginUser.getUsername())) {
//如果是超级管理员,赋予所有权限
list = functionDao.findAll();
} else {
//根据用户id查询所有权限
list = functionDao.findFunctionByUserId(loginUser.getId());
}
if (list != null && list.size() > 0) {
for (Function function : list) {
//为用户授权
simpleAuthorizationInfo.addStringPermission(function.getCode());
}
}
return simpleAuthorizationInfo;
} else {
return null;
}
}
七 查询用户权限的dao层方法
@SuppressWarnings("unchecked")
@Override
//根据用户id查询权限
public List<Function> findFunctionByUserId(String id) {
String hql = "from Function f left outer join fetch f.roles r "
+ "left outer join fetch r.users u where u.id = ?";
return this.getHibernateTemplate().find(hql, id);
}
Shiro入门之一 -------- Shiro权限认证与授权的更多相关文章
- Shiro集成web环境[Springboot]-认证与授权
Shiro集成web环境[Springboot]--认证与授权 在登录页面提交登陆数据后,发起请求也被ShiroFilter拦截,状态码为302 <form action="${pag ...
- shiro权限认证与授权
什么是shiro? Shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权.加密.会话管理等功能,组成了一个通用的安全认证框架. 为什么要用sh ...
- Shiro入门学习之shi.ini实现授权(三)
一.Shiro授权 前提:需要认证通过才会有授权一说 1.授权过程 2.相关方法说明 ①subject.hasRole("role1"):判断是否有该角色 ②subject.has ...
- 【一】shiro入门 之 Shiro简介
Shiro 可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE 环境,也可以用在JavaEE 环境.Shiro 可以帮助我们完成:认证.授权.加密.会话管理.与Web 集成.缓存等.这不就是 ...
- 权限认证与授权(Shrio 框架)
权限概述 认证: 系统提供的用于识别用户身份的功能, 通常登录功能就是认证功能; -- 让系统知道你是谁 授权: 系统授予用户可以访问哪些功能的证书. -- 让系统知道你能做什么! 常见的权限控制方式 ...
- Shiro入门学习之自定义Realm实现授权(五)
一.自定义Realm授权 前提:认证通过,查看Realm接口的继承关系结构图如下,要想通过自定义的Realm实现授权,只需继承AuthorizingRealm并重写方法即可 二.实现过程 1.新建mo ...
- Shiro入门之二 --------基于注解方式的权限控制与Ehcache缓存
一 基于注解方式的权限控制 首先, 在spring配置文件applicationContext.xml中配置自动代理和切面 <!-- 8配置自动代理 --> <bean cl ...
- springboot集成shiro实现权限认证
github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...
- Shiro learning - 入门学习 Shiro中的基础知识(1)
Shiro入门学习 一 .什么是Shiro? 看一下官网对于 what is Shiro ? 的解释 Apache Shiro (pronounced “shee-roh”, the Japanese ...
随机推荐
- 【一天一道LeetCode】#22. Generate Parentheses
一天一道LeetCode (一)题目 Given n pairs of parentheses, write a function to generate all combinations of we ...
- Leetcode_145_Binary Tree Postorder Traversal
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/42876769 Given a binary tree, r ...
- Cocos2D的随机数生成函数
有很多种方法生成随机数.但是只有arc4random函数生成的最接近于"真随机(truly random)"数.(而且不需要种子) 其变体函数arc4random_uniform生 ...
- Linux内核通用队列的使用笔记(读linux内核设计与实现)
Linux内核通用队列实现 Kfifo位置:kernel/kififo.c 使用需要包含头文件#include <kernel/kififo> 1.创建队列(动态创建)int kfifo_ ...
- Java进阶(十四)实现每天定时对数据库的操作
Java实现每天定时对数据库操作 现在有一个很棘手的问题:客户要求实现一个功能,就是每日凌晨自动计算慢性病订单是否有需要在今日提醒的,如果有则生成一条提醒记录到lm_notice之中. 如何在Web工 ...
- android 之ViewStub
在开发应用程序的时候,经常会遇到这样的情况,会在运行时动态根据条件来决定显示哪个View或某个布局.那么最通常的想法就是把可能用到的View都写在上面,先把它们的可见性都设为View.GONE,然后在 ...
- 【Java编程】随机数的不重复选择
随机数的不重复选择就是从n个数中随机选取m(m<n)个数.在本文中,我们用Java来实现.因此我们先介绍Java的相关知识. 在Java中,Java.util.Set接口和Java.util.L ...
- Objective-C的面向对象特性(一)
Objective-C在c语言的基础上增加了面向对象特性,都有哪些面向对象特性呢? 其中第一个最重要的特性是类和对象的实现. Objective-C软件由许多对象构成,形成一个对象网络,对象之间通过发 ...
- Android特效专辑(六)——仿QQ聊天撒花特效,无形装逼,最为致命
Android特效专辑(六)--仿QQ聊天撒花特效,无形装逼,最为致命 我的关于特效的专辑已经在CSDN上申请了一个专栏--http://blog.csdn.net/column/details/li ...
- Android绘图机制(三)——自定义View的实现方式以及半弧圆新控件
Android绘图机制(三)--自定义View的三种实现方式以及实战项目操作 在Android绘图机制(一)--自定义View的基础属性和方法 里说过,实现自定义View有三种方式,分别是 1.对现有 ...