shiro安全框架的使用流程
最近学了shiro安全框架流程,在这里梳理一下shiro的工作流程和一些代码,方便以后使用的时候,能快速找到对应的代码。
要使用这个shiro框架,还要新建两张表 t_authority(权限表)和t_role_authority(角色权限表)
1.先在porm.xml中引入四个jar包,分别是shiro-core(shiro核心包)、shiro-web(shiro服务包)、shiro-spring(shiro和spring整合包)和shiro-ehcache(shiro缓存包)
<shiro.version>1.3.2</shiro.version <dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>
2.在web.xml中配置filter(拦截器),拦截所有URL请求路径。
<!-- shiro过滤器定义 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 -->
<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>
3.在application.xml(spring.xml)中配置Realm、安全管理器和shiro过滤器
<!-- 配置自定义Realm -->
<bean id="myRealm" class="com.oracle.shiro.UserRealm">
<property name="credentialsMatcher" >
<bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
<property name="hashAlgorithmName" value="MD5"></property>
<property name="hashIterations" value="1024"></property>
</bean>
</property>
</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">
<!-- Shiro的核心安全接口,这个属性是必须的 -->
<property name="securityManager" ref="securityManager"/>
<!-- 身份认证失败,则跳转到登录页面的配置 -->
<property name="loginUrl" value="/login.html"/>
<property name="successUrl" value="/index.jsp"/>
<!-- 权限认证失败,则跳转到指定页面 -->
<property name="unauthorizedUrl" value="/login.htmls"/>
<!-- Shiro连接约束配置,即过滤链的定义 -->
<property name="filterChainDefinitions">
<value>
<!-- /candidate/admin/**=authc -->
<!--anon 表示匿名访问,不需要认证以及授权-->
/login.htmls = anon
/css/** = anon
/dist/** = anon
/js/** = anon
/user/loginIn.dodo = anon
/user/reg.dodo = anon
/res/** = anon
/logout = logout
<!--authc表示需要认证 没有进行身份认证是不能进行访问的-->
/**=authc
<!-- /student=roles[teacher]
/teacher=perms["user:create"]
--> </value>
</property>
</bean>
4.新建一个UserRealm类,该类的路径对应(3)中的自定义的Realm配置的class路径。
package com.oracle.shiro; import java.util.ArrayList;
import java.util.List; import javax.annotation.Resource; import org.apache.shiro.SecurityUtils;
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.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.util.StringUtils; import com.oracle.model.User;
import com.oracle.service.RoleService;
import com.oracle.service.UserService; public class UserRealm extends AuthorizingRealm {
// 用户对应的角色信息与权限信息都保存在数据库中,通过UserService获取数据
@Resource
private UserService userService; /**
* 提供用户信息返回权限信息
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String currentUsername = (String)super.getAvailablePrincipal(principals);
List<String> roleList = null; //用来存放角色码的集合
List<String> permissionList = null; //用来存放当前用户的权限码
//从数据库中获取当前登录用户的详细信息
User user = userService.findUserByUsername(currentUsername);
if(null != user){
permissionList = userService.getPermissions(user.getId());//根据当前登录用户的id,获取当前用户的权限码
roleList = userService.findRolesByUserId(user.getId());//根据当前用户的id,获取当前用户的角色码
}else{
throw new AuthorizationException();
}
//为当前用户设置角色和权限
SimpleAuthorizationInfo simpleAuthorInfo = new SimpleAuthorizationInfo();
simpleAuthorInfo.addRoles(roleList);//把用户角色码交给shiro
simpleAuthorInfo.addStringPermissions(permissionList);//把用户权限码交给shiro
return simpleAuthorInfo;
} /**
* 提供账户信息返回认证信息
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
String username = (String) token.getPrincipal();
User user = userService.findUserByUsername(username);
if (user == null) {
// 用户名不存在抛出异常
throw new UnknownAccountException();
}else{
ByteSource salt = ByteSource.Util.bytes(user.getSalt());//盐值
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user.getName(),
user.getPassWord(),salt,getName());
SecurityUtils.getSubject().getSession().setAttribute("CURRENT_USER", user);
return authenticationInfo;
} } }
注:在(4)中从数据库中获取用户信息的方法,比较简单,就不粘贴出来了(service->dao层->mapper.xml)
5.在spring-mvc.xml中配置,开启shiro注解,shiro才能被正式使用。
<!-- 开启Shiro注解 -->
<!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/> <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> <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.apache.shiro.authz.UnauthorizedException">
/unauthorized
</prop>
</props>
</property>
</bean>
登录、注册的controller中的代码:
package com.oracle.controller; import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.oracle.model.User;
import com.oracle.service.UserService; @Controller
@RequestMapping("/user")
public class UserController {
private static Logger log = Logger.getLogger(UserController.class);
@Autowired
private UserService userServiceNew; @RequestMapping("/reg")
@ResponseBody
public Map reg(User user) {
Map<String,Object> map = new HashMap<String,Object>();
// user.setPassWord(JavaUtilMD5.MD5(user.getPassWord()));
Random rd = new Random();
int salt = rd.nextInt(100000);
SimpleHash sh = new SimpleHash("MD5", user.getPassWord(),ByteSource.Util.bytes(salt+"") , 1024);
user.setPassWord(sh.toString());
user.setSalt(salt+"");
int i = userServiceNew.save(user);
if(i>0) {
map.put("code", 200);
}else {
map.put("code", 500);
}
return map;
}
@RequestMapping("/loginIn")
public String loginIn(User user,HttpSession session) {
if(user == null) {//
return "redirect:index.html?loginCode=500";
}else {
Subject subject = SecurityUtils.getSubject();
// 判断当前用户是否登陆
if (subject.isAuthenticated() == false) {
UsernamePasswordToken token = new UsernamePasswordToken(user.getName(), user.getPassWord());
try {
subject.login(token);
// Session session = subject.getSession();
// user = (SysUser) session.getAttribute(Constants.CURRENT_USER);
// session.setAttribute("SESSION_USERNAME", user.getId() + "");
// // 根据用户id查找用户角色
// SysUser u = this.findUserByUserId(user.getId());
// session.setAttribute("u", u);
return "index";
} catch (Exception e) {
// 这里将异常打印关闭是因为如果登录失败的话会自动抛异常
e.printStackTrace();
// model.addAttribute("error", "用户名或密码错误");
return "index";
}
} else {
// Session session = getSession();
// user = (SysUser) session.getAttribute(Constants.CURRENT_USER);
// session.setAttribute("SESSION_USERNAME", user.getId() + "");
return "index";
}
} } @Autowired
HttpServletRequest request;
@RequestMapping("/LoginInfo")
@ResponseBody
public Object Logininfo() {
HttpSession httpSession=request.getSession();
Object map=httpSession.getAttribute("CURR_USER");
return map;
} @RequestMapping("/findPageData")
@ResponseBody
public Object findPageData(Integer page,Integer rows) {
Integer startIndex = (page-1)*rows;
Map<String,Object> map = new HashMap<String,Object>();
map.put("startIndex", startIndex);
map.put("rows", rows);
List<User> users = userServiceNew.findPageData(map);
map.put("rows", users);
map.put("total", userServiceNew.findTotleSize());
return map;
}
@RequestMapping("/findAllUser")
@ResponseBody
public Object findAllUser() {
return userServiceNew.findAllUser();
} @RequestMapping("/user")
public String user() {
return "user";
} @RequestMapping("/userSave")
@ResponseBody
public Map userSave(User user) {
Map<String,Object> map = new HashMap<String,Object>();
int i = userServiceNew.save(user);
if(i>0) {
map.put("code", 200);
}else {
map.put("code", 500);
}
return map;
} @RequestMapping("/userUpdate")
@ResponseBody
public Map userUpdate(User user) {
Map<String,Object> map = new HashMap<String,Object>();
int i = userServiceNew.update(user);
if(i>0) {
map.put("code", 200);
}else {
map.put("code", 500);
}
return map;
} @RequestMapping("/userDelete")
@ResponseBody
public Map userDelete(User user) {
Map<String,Object> map = new HashMap<String,Object>();
int i = userServiceNew.delete(user.getId());
if(i>0) {
map.put("code", 200);
}else {
map.put("code", 500);
}
return map;
} @RequestMapping("/CurrUserMenu")
@ResponseBody
public Map<String,Object> findCurrUserMenu(){
User user = (User)SecurityUtils.getSubject().getSession().getAttribute("CURRENT_USER");
List<Map<String,Object>> menuList = userServiceNew.findCurrMenu(user.getId());
Map<String,Object> map = new HashMap<String,Object>();
map.put("code", 100);
map.put("msg", "");
Map<String,Object> m = new HashMap<String,Object>();
m.put("children", menuList);
map.put("extend", m);
return map;
}
}
shiro安全框架的使用流程的更多相关文章
- shiro安全框架
原文:http://blog.csdn.net/boonya/article/details/8233303 可能大家早先会见过 J-security,这个是 Shiro 的前身.在 2009 年 3 ...
- Shiro安全框架【快速入门】就这一篇!
Shiro 简介 照例又去官网扒了扒介绍: Apache Shiro™ is a powerful and easy-to-use Java security framework that perfo ...
- (转) shiro权限框架详解06-shiro与web项目整合(上)
http://blog.csdn.net/facekbook/article/details/54947730 shiro和web项目整合,实现类似真实项目的应用 本文中使用的项目架构是springM ...
- Shiro 安全框架详解一(概念+登录案例实现)
shiro 安全框架详细教程 总结内容 一.RBAC 的概念 二.两种常用的权限管理框架 1. Apache Shiro 2. Spring Security 3. Shiro 和 Spring Se ...
- Yii框架页面运行流程
Yii框架页面运行流程 CComponent | CModel | CActiveRecord.CFormModel(所有模型的父类) | 表名.php(模型) | 入口文件------------- ...
- thymeleaf模板引擎shiro集成框架
shiro权限框架.前端验证jsp设计.间tag它只能用于jsp系列模板引擎. 使用最近项目thymeleaf作为前端模板引擎,采用HTML档,未出台shiro的tag lib,假设你想利用这段时间s ...
- shiro权限框架(一)
不知不觉接触shiro安全框架都快三个月了,这中间配合项目开发踩过无数的坑.现在回想总结下,也算是一种积累,一种分享.中间有不够完美的地方或者不好的地方,希望大家指出来能一起交流.在这里谢谢开涛老师的 ...
- SpringBoot集成Shiro安全框架
跟着我的步骤:先运行起来再说 Spring集成Shiro的GitHub:https://github.com/yueshutong/shiro-imooc 一:导包 <!-- Shiro安全框架 ...
- 追源索骥:透过源码看懂Flink核心框架的执行流程
li,ol.inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-bottom:20px}dt, ...
随机推荐
- easyUI学习笔记一
1.引用js文件 <script type="text/javascript" src = jquery-easyui/jquery.min.js> </scri ...
- etcd扩展使用
etcd我已经提到很多次了,前面的可以自己查看.v3版本改用grpc接口,很简单,非常简单,易上手易学习. etcd有集群部署方式,那么就涉及部署的地址,可以动态添加部署节点,这样再应用中不可能都去关 ...
- Linux安装配置nfs实现共享远程目录
1. 服务端安装nfs yum -y install nfs-utils rpcbind 2.编辑/etc/exports /etc/exports文件内容格式: <输出目录> [客户端1 ...
- 浏览器中的JavaScript事件循环机制
浏览器的事件循环机制是HTML中定义的规范. JavaScript有一个主线程和调用栈,所有的任务都会被放到调用栈等待主线程执行. JS调用栈 是一种先进后出的数据结构.当函数被调用时,会被添加到栈中 ...
- jQuery 菜单 垂直菜单实现
HTML <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <ti ...
- cytoscape.js 教程
因为数据要展示双向关系,最终选用了cytoscape.js. 效果如图,echarts只能显示单项数据关系. 据我理解,这个插件分两种,一种是基于jquery的,另一种是原声的. 基于jquery是加 ...
- make编写教程(二)
1. make中的变量 makefile中的变量就是c/c++中的宏 2. 引用其他的make文件 类似于c语言中的#include,被包含的文件会原模原样的放在当前文件的包含位置. include& ...
- shell脚本编程测试类型下
一bash的数值测试 -v VAR变量VAR是否设置 数值测试:-gt 是否大于greater-ge 是否大于等于-eq 是否等于-ne 是否不等于 not equal-lt 是否小于-le 是否小 ...
- SSD接口详解,再也不会买错固态硬盘了
http://stor.51cto.com/art/201808/582349.htm 硬盘知识科普中,我们提到了SSD的发展史虽短,但是种类和协议比HDD不知道多到哪里去了.因此,本期小编就通过接口 ...
- 【软工项目Beta阶段】绝不划水队OUC-Market版本测试报告
我们在开发APP的时候进行了软件的测试,同时发现了一些BUG,如下: bug 我的:与各种页面之间的交互不灵活 登录与注册:记住密码功能不完善 商场主界面:搜索功能还没有完善 收藏功能:与数据库的交互 ...