权限概述
认证:系统提供的用于识别用户身份的功能,通常登录功能就是认证功能-----让系统知道你是谁??
授权:系统授予用户可以访问哪些功能的许可(证书)----让系统知道你能做什么??
常见的权限控制方式
-
URL拦截权限控制
底层基于拦截器或者过滤器实现
2.方法注解权限控制
底层基于代理技术实现,为Action创建代理对象,由代理对象进行权限校验
3.创建权限数据模型
- 权限表 : 其实就是各种功能模块
- 角色表
- 用户表
- 角色权限关系表
- 用户角色关系表
角色就是权限的集合,引入角色表,是为了方便授权
apache shiro框架简介
其实写好的一些过滤器拦截器
官网:shiro.apache.org
- 下载文件:
- shiro框架的核心功能:
认证
授权
会话管理
加密
这个很重要 这就是shiro的核心 (认证授权之后再进行权限控制)
流程:应用程序调用获得当前登录用户(这里还没有人认证)
然后当前用户调用安全管理器
安全管理器调用Realm
Realm 写具体的认证和授权
认证:检查用户 在检查密码
授权:是先从数据库中获得该用户的权限在加上去
shiro其实就是改变了登录的代码 再登录到时候进行认证和授权
- shiro框架认证流程
Application Code:应用程序代码,由开发人员负责开发的
Subject:框架提供的接口,代表当前用户对象
SecurityManager:框架提供的接口,代表安全管理器对象
Realm:可以开发人员编写,框架也提供一些,类似于DAO,用于访问权限数据
在BOS项目中应用shiro框架进行认证
第一步:引入shiro框架相关的jar
第二步:在web.xml中配置spring框架提供的用于整合shiro框架的过滤器(这是个固定的一定要配置)
启动tomcat服务器,抛出异常:spring工厂中不存在一个名称为“shiroFilter”的bean对象
第三步:在spring配置文件中配置bean,id为shiroFilter
配置过滤器工厂
元素有:安全管理器
登录成功之后跳转的页面
没有登录跳到的登录页面
没有权限的时候跳到的页面
权限控制:根据不同的访问目录设置权限
框架提供的过滤器:
第四步:配置安全管理器
第五步:修改UserAction中的login方法,使用shiro提供的方式进行认证操作
public String login(){
//从Session中获取生成的验证码
String validatecode = (String) ServletActionContext.getRequest().getSession().getAttribute("key");
//校验验证码是否输入正确
if(StringUtils.isNotBlank(checkcode) && checkcode.equals(validatecode)){
//使用shiro框架提供的方式进行认证操作
Subject subject = SecurityUtils.getSubject();//获得当前用户对象,状态为“未认证”
//用户密码令牌
AuthenticationToken token = new UsernamePasswordToken(model.getUsername(),MD5Utils.md5(model.getPassword()));//创建用户名密码令牌对象
try{
subject.login(token);//进行认证
}catch(Exception e){
e.printStackTrace();
return LOGIN;
}
User user = (User) subject.getPrincipal();//进行授权 得到具有经过认证授权的用户
ServletActionContext.getRequest().getSession().setAttribute("loginUser", user);//把用户放入session中
return HOME;
}else{
//输入的验证码错误,设置提示信息,跳转到登录页面
this.addActionError("输入的验证码错误!");
return LOGIN;
}
}
第六步:自定义realm,并注入给安全管理器
public class BOSRealm extends AuthorizingRealm{
@Autowired
private IUserDao userDao;
//认证方法
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
System.out.println("realm中的认证方法执行了。。。。");
UsernamePasswordToken mytoken = (UsernamePasswordToken)token;
String username = mytoken.getUsername();
//1.根据用户名查询数据库中的密码
User user = userDao.findUserByUserName(username);
if(user == null){
//用户名不存在
return null;
}
//2.如果能查询到,再由框架比对数据库中查询到的密码和页面提交的密码是否一致
AuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
return info;
}
//授权方法
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//为用户授权
info.addStringPermission("staff-list");
//TODO 后期需要修改为根据当前登录用户查询数据库,获取实际对应的权限???
User user1 = (User) SecurityUtils.getSubject().getPrincipal();
User user2 = (User) principals.getPrimaryPrincipal();
System.out.println(user1 == user2);
return info;
}
- 修改Realm中授权方法(查询数据库)
//授权方法
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
//获取当前登录用户对象
User user = (User) SecurityUtils.getSubject().getPrincipal();//获得当前用户
//User user2 = (User) principals.getPrimaryPrincipal();
// 根据当前登录用户查询数据库,获取实际对应的权限
List<Function> list = null;
if(user.getUsername().equals("admin")){
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Function.class);
//超级管理员内置用户,查询所有权限数据
list = functionDao.findByCriteria(detachedCriteria);
}else{
list = functionDao.findFunctionListByUserId(user.getId());
}
for (Function function : list) {
info.addStringPermission(function.getCode());//把用户的权限查询出来之后放进来可以了
}
return info;
}
总结shiro框架提供的权限控制方式
-
使用shiro的方法注解方式权限控制
第一步:在spring配置文件中开启shiro注解支持
<!-- 开启shiro框架注解支持 -->
<bean id="defaultAdvisorAutoProxyCreator"
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
<!-- 必须使用cglib方式为Action对象创建代理对象??? 代理对象的作用和应用??? -->
<property name="proxyTargetClass" value="true"/>
</bean>
<!-- 配置shiro框架提供的切面类,用于创建代理对象 -->
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"/>
第二步:在Action的方法上使用shiro注解
第三步:在struts.xml中配置全局异常捕获,当shiro框架抛出权限不足异常时,跳转到权限不足提示页面
- 使用shiro提供的页面标签方式权限控制
第一步:在jsp页面中引入shiro的标签库
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>
第二步:使用shiro的标签控制页面元素展示
-
URL拦截权限控制(基于过滤器实现) 访问路径
总结:
- 先认证授权在进行权限管理 ,认证授权的流程如上所示,简单理解如下图:
- 有三种常用的授权方式,可以一起使用
方法注解权限控制(基于代理技术实现) 后台action中
页面标签权限控制(标签技术实现) 前台
URL拦截权限控制(基于过滤器实现) 访问路径
- shiro其实就是改变了登录的代码 在登录到时候进行认证和授权,做了一些权限案例 (加了一些配置(application中,web.xml) 一些注解 一些标签 )
具体看文档