基础介绍
shiro 是一个安全框架 有认证和授权 加密 会话管理等功能.
内置9个过滤器用于对数据进行过滤 (anon,authc,prem)
如何使用:步骤1:导入jar包(4个分别为shiro-web,spring,aspject,core)
步骤2:导入配置文件:application_shiro.xml(配置核心组件,安全管理器等)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="erpAuthorizationFilter" class="cn.itcast.erp.authorfilter.ErpAuthorizationFilter"></bean>
<!-- shiro过滤器工厂bean 相当于加载了9个内置过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<!-- 安全管理器: 核心组件 -->
<property name="securityManager" ref="securityManager" />
<!-- 认证相关配置:如果没有通过认证就跳转到对应界面 -->
<property name="loginUrl" value="/login.html" />
<!-- 授权相关配置: 当用户访问了某个没有的权限时 页面跳转的位置 -->
<property name="unauthorizedUrl" value="/error.html" />
<property name="filters">
<map>
<entry key="prems" value-ref="erpAuthorizationFilter"></entry>
</map>
</property>
<!-- 过滤器的定义 其中的值 用于配置页面的访问规则 -->
<property name="filterChainDefinitions">
<value>
<!-- anon:表示可以无认证(未登录)通过 -->
/error.html = anon
/login_*=anon
<!-- url配置 -->
/goodstype.html=perms["商品类型管理"]
/orders.html=perms["新增管理","审核管理","确认管理","入库管理","订单管理","销售订单新增","销售订单出库"]
/orders_add.action= perms["新增管理","销售订单新增"]
/orders_doCheck.action=perms["审核管理"]
/orders_doStart.action=perms["确认管理"]
/orderdetail_doOutStore.action=perms["销售订单出库"]
/orderdetail_doInStore.action=perms["入库管理"]
/goodstype_*=perms["商品类型管理"]
<!-- authc:需要登录才可以 -->
/*.action=authc
/*.html = authc
/*=authc
</value>
</property>
</bean>
<!-- 安全管理器:核心组件(大脑) -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="erpRealm"></property>
</bean>
<!-- 定义自己实现的realm类 并且将其注入到 安全管理器中-->
<bean id="erpRealm" class="cn.itcast.erp.realm.ErpRealm">
<!-- 注入实现类过程中使用的元素-->
<property name="empBiz" ref="empBiz"></property>
<property name="menuBiz" ref="menuBiz"> </property>
</bean>
<!-- 开启shiro注解 -->
<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor" >
<!-- 默认使用JDK代理 ,如被代理类没有实现接口,必须使用下列配置开启 cglib代理 -->
<property name="proxyTargetClass" value="true" />
</bean>
<bean
class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
<property name="securityManager" ref="securityManager" />
</bean>
<!-- 对安全管理器 增强代码 , spring 后处理器 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
</beans>
步骤3:配置web.xml中配置过滤器 (注意配置位置要在struts2之前)
配置完成之后开始基础功能
<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>*.action</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>*</url-pattern>
</filter-mapping>
认证功能
即登录功能(采用 令牌+subject(主题)+事件格式)
步骤1:将之前的调用biz层的代码修改为创建对应的登录代码
//创建令牌
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username,pwd1);
//创建主题
Subject subject = SecurityUtils.getSubject();
//调用主题事件login();login为系统自带的
subject.login(usernamePasswordToken);
ajaxReturn(true, "");
步骤2: 创建令牌会自己调用 realm中的功能,所以我们需要自己重写realm 类 继承自authenticathingRealem 重写两个方法 认证方法 和授权方法.
package cn.itcast.erp.realm;
import java.util.List;
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.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import cn.itcast.erp.biz.IEmpBiz;
import cn.itcast.erp.biz.IMenuBiz;
import cn.itcast.erp.entity.Emp;
import cn.itcast.erp.entity.Menu;
/**
* @author 66
* 自定义 realm 类 继承自 authrizingRealm
* 实现了两个方法 一个为授权方法 一个为认证方法
*/
public class ErpRealm extends AuthorizingRealm{
// 注入empbiz 用于获取用户名和密码I
private IEmpBiz empBiz;
private IMenuBiz menuBiz;
public void setMenuBiz(IMenuBiz menuBiz) {
this.menuBiz = menuBiz;
}
public void setEmpBiz(IEmpBiz empBiz) {
this.empBiz = empBiz;
}
/* (non-Javadoc)
* @授权方法
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// TODO Auto-generated method stub
System.out.println("授权方法");
// 在授权方法中对用户的权限 进行授权
// 步骤1:获得当前的用户信息
Emp emp = (Emp) principals.getPrimaryPrincipal();
// 步骤2:获取菜单集合
List<Menu> list = menuBiz.getMenusByEmpuuid(emp.getUuid());
//定义一个简易授权信息
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
for (Menu menu : list) {
// 将菜单遍历加入到 对象中
//赋值给简易授权信息
info.addStringPermission(menu.getMenuname());
}
// 将简易授权信息返回给//
return info;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// TODO Auto-generated method stub
System.out.println("认证方法");
// 实现认证方法 通过访问 iempbiz 来判断是否密码是否正确
// 将携带的令牌 传给一个自定义的 用户密码令牌
UsernamePasswordToken upt= (UsernamePasswordToken) token;
String pwd = new String(upt.getPassword());
// 通过令牌中的用户名和密码调用 emp方法 查看用户是否存在
Emp emp = empBiz.findByPasswordAndPassword(upt.getUsername(), pwd);
// 如果用户存在 则使用
if (null!=emp) {
// 返回结果为: 简易授权信息 包括
// 参数1:主角,就是登陆的用户
// 参数2:证书凭证,或者密码
// 参数3:当前realm 的名称
return new SimpleAuthenticationInfo(emp,pwd,getName());
}
// 如果用户不存在就返回为空
return null;
}
}
重写之后将其配置到shiro中.见applicatioon-shiro图
之后可以通过
SecurityUtils.getSubject().getPrincipal();来得到用户名 用于页面返回.
可以调用subject 的logout来退出登录.
授权功能:
需要重写 对应的realm中的方法
配置核心配置文件中数据
分为三块 1:粗颗粒 2:细颗粒
1粗颗粒经常用于url 对网址进行授权 但是如果多个功能使用了同一个页面,就需要使用细颗粒 包括两种一:对方法的 2:对代码的. 需要进行对应的prem配置