一、前言
第一篇我们注意讲解了一些基础。接下来我们看看具体权限解决方案。
二、权限解决方案
2.1 资源分类
针对第一篇中的出现资源分类,这里做强调讲解。资源分类注意包括:粗粒度和细粒度。
1、粗粒度权限:资源权限类型的管理。例如:部门操作、用户信息操作 统一拦截处理(可框架)
2、细粒度权限:资源权限类型实例的管理。具体到相应数据集。例如:销售部操作、ycy用户信息操作 业务层处理
例如:user类 与 张三的关系
三、基于URL的拦截
3.1基础框架搭建
由于主要讲解权限框架,所以springMVC+mybatis的东西,不懂的同学请移步springMVC教程和mybatis教程。除此之外还有easyui的一些前端东西, 这个你懂且可以,本人一向不擅长前端,只是会用,要高端的js我也搞不出(也不建议搞java的人去攻前端)。建议框架选择:直接从我的git上面下载,或者用springmvc教程项目改。
3.2基于url拦截-用户认证实现
看图说话:绿色即是我们的
用户认证,蓝色为
权限控制。暂时我们只看认证
1、用户认证思路:通过用户身份和密码进行认证,如果认真通过,则保存在session里面。
接下来我们按照底层到页面开始开发:dao-mapper-service-controller-intercepter-web页面
3.2.1 建立service与mapper:完成认证
mapper:
SysUserMapper.java:
package com.ycy.mapper; import java.util.List; import com.ycy.model.SysUser; import org.apache.ibatis.annotations.Param; public interface SysUserMapper { /** * 根据用户查询用户系统信息 * @param usercode * @return */ List<SysUser> getSysUserByUserCode(String usercode); }
mapper.xml
SysUserMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.ycy.mapper.SysUserMapper" > <resultMap id="BaseResultMap" type="com.ycy.model.SysUser" > <id column="id" property="id" jdbcType="VARCHAR" /> <result column="usercode" property="usercode" jdbcType="VARCHAR" /> <result column="username" property="username" jdbcType="VARCHAR" /> <result column="password" property="password" jdbcType="VARCHAR" /> <result column="salt" property="salt" jdbcType="VARCHAR" /> <result column="locked" property="locked" jdbcType="CHAR" /> </resultMap> <!--基础属性--> <sql id="Base_Column_List" > id, usercode, username, password, salt, locked </sql> <!--根据用户名查询系统用户--> <select id="getSysUserByUserCode" resultMap="BaseResultMap" parameterType="map" > select <include refid="Base_Column_List" /> from sys_user WHERE usercode=#{usercode} </select> </mapper>
SysService:
package com.ycy.service; import com.ycy.model.ActiveUser; import java.util.List; /** * * <p>Title: SysService</p> * <p>Description: 认证授权服务接口</p> */ public interface SysService { //根据用户的身份和密码 进行认证,如果认证通过,返回用户身份信息 public ActiveUser authenticat(String userCode, String password) throws Exception; }
ItemsServiceImpl
package com.ycy.service.impl; import java.util.List; import com.ycy.Exception.CustomException; import com.ycy.mapper.SysUserMapper; import com.ycy.model.ActiveUser; import com.ycy.model.SysUser; import com.ycy.service.SysService; import com.ycy.util.MD5; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * * <p>Title: SysServiceImpl</p> * <p>Description:认证和授权的服务接口 </p> */ @Service public class SysServiceImpl implements SysService { @Autowired private SysUserMapper sysUserMapper; @Override public ActiveUser authenticat(String userCode, String password) throws Exception { /** 认证过程: 根据用户身份(账号)查询数据库,如果查询不到用户不存在 对输入的密码 和数据库密码 进行比对,如果一致,认证通过 */ //根据用户账号查询数据库 SysUser sysUser = this.findSysUserByUserCode(userCode); if(sysUser == null){ //抛出异常 throw new CustomException("用户账号不存在"); } //数据库密码 (md5密码 ) String password_db = sysUser.getPassword(); //对输入的密码 和数据库密码 进行比对,如果一致,认证通过 //对页面输入的密码 进行md5加密 String password_input_md5 = new MD5().getMD5ofStr(password); if(!password_input_md5.equalsIgnoreCase(password_db)){ //抛出异常 throw new CustomException("用户名或密码 错误"); } //得到用户id String userid = sysUser.getId(); //认证通过,返回用户身份信息 ActiveUser activeUser = new ActiveUser(); activeUser.setUserid(sysUser.getId()); activeUser.setUsercode(userCode); activeUser.setUsername(sysUser.getUsername());//用户名称 return activeUser; } //根据用户账号查询用户信息 private SysUser findSysUserByUserCode(String userCode)throws Exception{ List<SysUser> list = sysUserMapper.getSysUserByUserCode(userCode); if(list!=null && list.size()==1){ return list.get(0); } return null; } }
3.2.2 controller:完成数据认证与保存session
LoginController.java:
package com.ycy.controller; import javax.servlet.http.HttpSession; import com.ycy.Exception.CustomException; import com.ycy.model.ActiveUser; import com.ycy.service.SysService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * * <p>Title: LoginController</p> * <p>Description: 登陆和退出</p> */ @Controller public class LoginController { @Autowired private SysService sysService; //用户登陆提交方法 @RequestMapping("/login") public String login(HttpSession session,String usercode,String password,String randomcode)throws Exception{ //校验验证码 //从session获取正确的验证码 String validateCode = (String)session.getAttribute("validateCode"); if(!randomcode.equals(validateCode)){ //抛出异常:验证码错误 throw new CustomException("验证码 错误 !"); } //用户身份认证 ActiveUser activeUser = sysService.authenticat(usercode, password); //记录session session.setAttribute("activeUser", activeUser); //重定向到商品查询页面 return "redirect:/first"; } //用户退出 @RequestMapping("/logout") public String logout(HttpSession session)throws Exception{ //session失效 session.invalidate(); //重定向到商品查询页面 return "redirect:/items/queryItems"; } }3.2.3用户身份认证拦截器:拥有权限验证
package com.ycy.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.ycy.model.ActiveUser; import com.ycy.util.ResourcesUtil; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import java.util.List; /** * * <p>Title: HandlerInterceptor1</p> * <p>Description: 用户身份认证拦截器</p> */ public class LoginInterceptor implements HandlerInterceptor { //在执行handler之前来执行的 //用于用户认证校验、用户权限校验 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //得到请求的url String url = request.getRequestURI(); //判断是否是公开 地址 //实际开发中需要公开 地址配置在配置文件中 //从配置中取逆名访问url List<String> open_urls = ResourcesUtil.gekeyList("config/anonymousURL"); //遍历公开 地址,如果是公开 地址则放行 for(String open_url:open_urls){ if(url.indexOf(open_url)>=0){ //如果是公开 地址则放行 return true; } } //判断用户身份在session中是否存在 HttpSession session = request.getSession(); ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser"); //如果用户身份在session中存在放行 if(activeUser!=null){ return true; } //执行到这里拦截,跳转到登陆页面,用户进行身份认证 request.getRequestDispatcher("/pages/jsp/login.jsp").forward(request, response); //如果返回false表示拦截不继续执行handler,如果返回true表示放行 return false; } //在执行handler返回modelAndView之前来执行 //如果需要向页面提供一些公用 的数据或配置一些视图信息,使用此方法实现 从modelAndView入手 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("HandlerInterceptor1...postHandle"); } //执行handler之后执行此方法 //作系统 统一异常处理,进行方法执行性能监控,在preHandle中设置一个时间点,在afterCompletion设置一个时间,两个时间点的差就是执行时长 //实现 系统 统一日志记录 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("HandlerInterceptor1...afterCompletion"); } }
3.2.3easyUI等问题
关于easyui与验证码的视频和教程网上很多。建议去看看。这里你最好下载我们的项目修改,或者直接用我项目吧。前端是苦逼的。