权限控制
常见的权限控制
1\URL 拦截权限控制
通过拦截器或者过滤器拦截客户端发送的请求,在拦截器或者过滤器中判断当前用户是否具有访问权限有就放行,没有权限 跳转到权限不足的提示页面
2\方法注解权限控制
基于代理技术实现 有代理对象进行权限校验
权限数据模型
1\权限表
2\角色表
就是权限的集合
3\用户表
4\角色权限关系表
5\用户角色关系表
shrio
核心功能
1\认证
2\授权
3\会话管理
4\加密
Authentication:身份认证 / 登录,验证用户是不是拥有相应的身份;
Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;
maven 引用:
org.apache.shiro shiro-core 1.2.3 org.apache.shiro shiro-spring 1.2.3 org.apache.shiro shiro-cas 1.2.3 commons-logging commons-logging org.apache.shiro shiro-web 1.2.3 org.apache.shiro shiro-ehcache 1.2.3 org.apache.shiro shiro-quartz 1.2.3
Application Code
应用程序代码 开发人员开发
Subject
框架提供的接口 代表当前用户对象
SecurityManager
框架提供的接口 代表安全管理器对象 ***********
Realm
开发人员可以编写,框架也提供一些 类似DAO 用于访问权限数据
使用
1\在项目中引入maven 依赖
2\在web.xml 配置一个过滤器
shiroFilter org.springframework.web.filter.DelegatingFilterProxy shiroFilter /*
3\在spring 配置文件中配置beanid和上面的过滤器的名称一样
/css/** = anon /js/** = authc /images/** = anon /validatecode.jsp* = anon /index.jsp = anon /toLogin.do = anon /user/login.do = anon /user/** = perms["user-list"] /page.do = perms["page-list"] /* = authc
过滤器名称过滤器类描述
anonorg.apache.shiro.web.filter.authc.AnonymousFilter匿名过滤器
authcorg.apache.shiro.web.filter.authc.FormAuthenticationFilter当前用户是否已经登录
authcBasicorg.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter基本http验证过滤,如果不通过,跳转屋登录页面
logoutorg.apache.shiro.web.filter.authc.LogoutFilter登录退出过滤器
noSessionCreationorg.apache.shiro.web.filter.session.NoSessionCreationFilter没有session创建过滤器
permsorg.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter权限过滤器
portorg.apache.shiro.web.filter.authz.PortFilter端口过滤器,可以设置是否是指定端口如果不是跳转到登录页面
restorg.apache.shiro.web.filter.authz.HttpMethodPermissionFilterhttp方法过滤器,可以指定如post不能进行访问等
rolesorg.apache.shiro.web.filter.authz.RolesAuthorizationFilter角色过滤器,判断当前用户是否指定角色
sslorg.apache.shiro.web.filter.authz.SslFilter请求需要通过ssl,如果不是跳转回登录页
userorg.apache.shiro.web.filter.authc.UserFilter如果访问一个已知用户,比如记住我功能,走这个过滤器
4\登录Controller
//使用shiro 框架提供的方式进行认证操作 Subject subject = SecurityUtils.getSubject();//获取当前用户对象,状态为:未认证 AuthenticationToken token = new UsernamePasswordToken(username, MD5Utils.md5(password)); try { subject.login(token); } catch (Exception e) { e.printStackTrace(); result = "login"; } user = (User) subject.getPrincipal(); session.setAttribute("user", user); session.setMaxInactiveInterval(60*60*24); result = "redirect:../pages_common_index.do";
5\写Realm
Exception 类型:
没有这个用户名
UnknownAccountException
密码错误
IncorrectCredentialsException
package com.stevezong.bos.realm; import javax.annotation.Resource; 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.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; import com.stevezong.bos.dao.UserMapper; import com.stevezong.bos.entity.User; public class BosRealm extends AuthorizingRealm{ @Resource UserMapper userMapper; //认证方法 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { System.out.println("自定义Realm"); //根据用户名查询数据库中的密码 //将AuthenticationToken 强转为 UsernamePasswordToken 方便使用 UsernamePasswordToken passwordToken = (UsernamePasswordToken) token; //根据用户名查询数据中的User对象 User user = userMapper.findByUsername(passwordToken.getUsername()); if(user == null) { //页面输入的用户名不存在 return null; }else { //简单认证信息对象(user对象,数据库中的密码,任意字符串) AuthenticationInfo info = new SimpleAuthenticationInfo(user,user.getPassword(),this.getName()); //框架负责对比数据库中的密码和页面输入的密码是否一致 return info; } } //授权方法 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) { // TODO 后期需要修改为根据当前登录永固查询数据库获取实际对应的权限 SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addStringPermission("staff-list"); return info; } }
shiro 注解
1\
2\在对应的方法上加上注解
@RequiresPermissions("权限名称")
package com.stevezong.bos.controller; import javax.annotation.Resource; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.stevezong.bos.service.StaffService; import com.stevezong.bos.utils.BosResult; @Controller @RequestMapping("/staff") public class StaffDelController { @Resource(name = "staffService") StaffService staffService; @RequestMapping("/del.do") @ResponseBody @RequiresPermissions("staff-delete") public BosResult