网站开发,就会涉及到人员登录,人员呢就会有权限。今天就理一下Springmvc的权限实现过程。
1.首先要知道@AuthPassport这个注解。这个注解能就是实现权限验证的注解。
2.在需要验证权限的Controller的方法上添加注解
@AuthPassport//权限验证
@AuthPassport(validate=false)//validate默认为true,表示需要验证,当validate 为false时表示不需要验证
@AuthPassport(authority="common")//只有有common权限的才可以调用方法
@AuthPassport(authority = Const.AUTH_LOG)//只有有Const.AUTH_LOG常量权限的才可以调用方法
以上是我的项目中常用的权限注解方式。
3.配置项目的springservlet-config.xml或者springmvc.xml中添加如下内容:
这样在执行每个action方法是都会调用AuthInterceptor处理,当判断action上有我们定义AuthPassport注解时就会执行里面的权限验证逻辑。
<mvc:interceptors>
<!-- 国际化操作拦截器 如果采用基于(请求/Session/Cookie)则必需配置 -->
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" />
<!-- 如果不定义 mvc:mapping path 将拦截所有的URL请求 -->
<bean class="com.tj720.mip.framework.auth.AuthInterceptor"></bean>
</mvc:interceptors>
其中第一个bean是spring-webmvc的jar包中的
另外一个bean就是自己写的权限实现文件
package com.tj720.mip.framework.auth; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Inherited @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AuthPassport { boolean validate() default true; String authority() default ""; }
package com.tj720.mip.framework.auth; import java.net.InetAddress; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import com.tj720.mip.framework.MyException; import com.tj720.mip.inter.dao.ICacheDao; import com.tj720.mip.springbeans.Config; import com.tj720.mip.springbeans.GetBeanByConfig; import com.tj720.mip.utils.Aes; import com.tj720.mip.utils.Const; import com.tj720.mip.utils.MyCookie; import com.tj720.mip.utils.MyString; import com.tj720.mip.utils.Tools; /** * 对登录状态进行拦截 * @author * */ public class AuthInterceptor extends HandlerInterceptorAdapter { @Autowired private GetBeanByConfig getBEanByConfig; @Autowired private Config config; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if(handler.getClass().isAssignableFrom(HandlerMethod.class)){ AuthPassport authPassport = ((HandlerMethod) handler).getMethodAnnotation(AuthPassport.class); // 未登陆用户唯一识别 String uuid = MyCookie.getCookie(Const.COOKIE_UUID, false, request); if( MyString.isEmpty(uuid) ){ MyCookie.addCookie(Const.COOKIE_UUID, System.currentTimeMillis() + Tools.getChar(10), response); } try{ // 返回服务器ip response.setHeader("serviceIp", InetAddress.getLocalHost().getHostAddress()); }catch(Exception e){ e.printStackTrace(); response.setHeader("serviceIp", "服务器配置异常,无法获取服务器IP"); } if(authPassport == null || authPassport.validate() == false) return true; String token = MyCookie.getCookie(Const.COOKIE_TOKEN, false, request); String uid = MyCookie.getCookie(Const.COOKIE_USERID, false, request); // 前端没有传递token,未登录 if(MyString.isEmpty(token) || MyString.isEmpty(uid) || !Aes.desEncrypt(token).equals(uid)){ if(request.getRequestURI().endsWith("admin.do")) response.sendRedirect("loginOrRegister.do#/login"); else{ String acceptHeader = request.getHeader("Accept"); String ajaxParam = request.getParameter("text/html;type=ajax"); if ("text/html;type=ajax".equals(acceptHeader) || StringUtils.hasText(ajaxParam)) { throw new MyException("000021"); } else { response.sendRedirect(request.getContextPath()+"/toLogin.do"); } } } // 后端没登录信息:登录超时 ICacheDao cacheDao = getBEanByConfig.getCacheDao(); Object obj = cacheDao.getObj(Const.CACHE_USER + uid); if(obj == null){ // 删除cookie MyCookie.deleteCookie(Const.COOKIE_TOKEN, request, response); if(request.getRequestURI().endsWith("admin.do")){ response.sendRedirect("loginOrRegister.do#/login"); return false; } else{ String acceptHeader = request.getHeader("Accept"); String ajaxParam = request.getParameter("text/html;type=ajax"); if ("text/html;type=ajax".equals(acceptHeader) || StringUtils.hasText(ajaxParam)) { throw new MyException("000021"); } else { response.sendRedirect(request.getContextPath()+"/toLogin.do"); return false; } } } // 每次访问,将用户登录有效信息延长 cacheDao.setObj(Const.CACHE_USER + uid, obj, config.getLoginInforTime()); if(!authPassport.authority().equals("")){ return Tools.hasAuth(authPassport.authority()); }else{ return true; } } else return true; } }
4.在LoginController中
5.在LoginInfoDto中要放登陆者用到的所有信息字段
6.查出用户的所有权限,用,分割
7.在需要的权限的方法前边加注解
8.在jsp页面判断等级为3的显示if标签中的内容
9.判断有edit权限的可以看到if标签下的内容
10.当然,在jsp页面要加标签
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
11总结思路:
首先配置spring权限验证的配置文件,
在登录按钮中加方法去login方法中验证用户名密码是否正确,
如果正确将user对象放到session和cookie中。
这样在执行每个action方法是都会看有没有@AuthPassport注解,
如果有就调用AuthInterceptor处理,执行权限验证逻辑。
其中涉及的表是user表和auth表