利用自定义注解和拦截器为信息安全存在问题的老Java Web系统添加鉴权能力

公司的系统比较老了,再加上成本限制,信息安全方面做的不够好,菜单的权限分配是靠判断是否在首页展示给用户来决定的,如果有人能够拿到未被展示的菜单中执行相关业务逻辑的url(比如修改密码的url:/user/changePassword),即使没有权限也能进入。
由于数据库中只存储了用户与角色的关联、角色与菜单项的关联信息,并没有存储用户或角色与具体业务逻辑url之间的关联信息,因此我想到了利用拦截器来实现鉴权功能,虽然略微有些麻烦,但至少应该比将业务逻辑url也录入进去再重新给用户分配权限来的容易。
各位看官如果有什么更好的办法,欢迎分享!

  • 首先是自定义注解:
package cn.bzdj.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;

/**
 - 自定义注解,用于鉴权
 - @author bzdj
 -  */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuthUrl {
	//参数填写父级url,拥有任意父级url的访问权限,即拥有被注解的controller的访问权限
	String[] urls();
}
  • 然后是拦截器:
package cn.bzdj.interceptor;

import java.math.BigDecimal;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import cn.bzdj.annotation.AuthUrl;

/**
 * 利用注解AuthUrl来鉴权
 * @author bzdj
 *  */
public class PrevilegeInterceptor extends HandlerInterceptorAdapter {
	
	@Autowired
	PrevilegeMapper pm; //这里换成自己鉴权用到的mapper

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		String[] urls=null;
	    if(handler instanceof HandlerMethod) {
	        HandlerMethod h = (HandlerMethod)handler;
	        if(h.getMethodAnnotation(AuthUrl.class)==null) //无AuthUrl注解则放行
	        	return true;
	        urls=h.getMethodAnnotation(AuthUrl.class).urls();
	        if(urls==null||urls.length==0)  //空AuthUrl注解则放行
	        	return true;
	        //这里填写自己的判断当前用户是否拥有权限的代码,如果有则return true。
	    }else{
	    	return true; //放行静态资源(spring mvc 3.2及以上版本可在xml或配置类中配置)
	    }
	    response.sendRedirect(request.getContextPath()+"/index.jsp"); //无权限则重定向到首页
		return false;
	}
	
}
  • 之后是配置:
	<mvc:interceptors>
			<bean class="cn.bzdj.interceptor.PrevilegeInterceptor" />
	</mvc:interceptors>

如果spring mvc版本在3.2及以上,可在此处配置放行静态资源。其他配置差别自行查看相关文档或百度。

  • 最后是使用:
    还拿上面修改密码为例
@PostMapping("/changePassword")
@ResponseBody
@AuthUrl(urls={"/a","/b","/c"}) //引号中填写需要拥有哪些菜单的访问权限才能使用此url,有多少个就填多少个,不需要鉴权的不加此注解
public Json changePassword(User user){
	//相关业务逻辑
}
  • 总结:
    由于数据库仅存储了菜单权限,子级url是否有权限只能通过这些菜单的url进行判断,因此想到了拦截器+自定义注解的方法。之所以不用AOP,原因是需要拿到session中存储的相关数据,用拦截器更加方便。如果各位看官觉得代码还可以再简化,或者有更好的解决方案,欢迎留言讨论!
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值