SpringMVC給控制器添加自定義注解控制訪問權限

vqfq6057 8年前發布 | 6K 次閱讀 Java Spring

場景描述:現在需要對部分Controller或者Controller里面的服務方法進行權限攔截。如果存在我們自定義的注解,通過自定義注解提取所需的權限值,然后對比session中的權限判斷當前用戶是否具有對該控制器或控制器方法的訪問權限。如果沒有相關權限則終止控制器方法執行直接返回。有兩種方式對這種情況進行處理。

方式一:使用SpringAOP中的環繞Around
方式二:使用Spring web攔截器
</div>

 

定義注解    

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
//最高優先級
@Order(Ordered.HIGHEST_PRECEDENCE)
public @interface RoleControl {
    /**
     * 
     * 角色類型,以便決定是否具有相關權限
     */
    String value() default "user";
}

在Controller中使用    

@RoleControl("ADMIN")
@Controller
public class LoginController {
    @Autowired
    private UserService uService;
    @Autowired
    private GlobalConfigService gcService;
    @RoleControl("")
    @RequestMapping("/login")
    public String login(HttpServletRequest request,HttpServletResponse resp, @ModelAttribute("user") UserDto uDto) {
           return ""
}

方式一:使用SpringAOP中的環繞Around    

@Component
@Aspect
public class RoleControlAspect {

    /**類上注解情形 */
//  @Pointcut("@within(net.xby1993.springmvc.annotation.RoleControl)")
    @Pointcut("execution(* net.xby1993.springmvc.controller..*.*(..)) && @within(net.xby1993.springmvc.annotation.RoleControl)")
    public void aspect(){

    }
    /**方法上注解情形 */
    @Pointcut("execution(* net.xby1993.springmvc.controller..*.*(..)) && @annotation(net.xby1993.springmvc.annotation.RoleControl)")
    public void aspect2(){

    }
    /**aop實際攔截兩種情形*/
    @Around("aspect() || aspect2()")
    public Object doBefore(ProceedingJoinPoint point) {
                    HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
        HttpSession session=request.getSession();
        Object target = point.getTarget();
        String method = point.getSignature().getName();
        Class<?> classz = target.getClass();
        Method m = ((MethodSignature) point.getSignature()).getMethod();
        try {
            if (classz!=null && m != null ) {
                boolean isClzAnnotation= classz.isAnnotationPresent(RoleControl.class);
                boolean isMethondAnnotation=m.isAnnotationPresent(RoleControl.class);
                RoleControl rc=null;
                //如果方法和類聲明中同時存在這個注解,那么方法中的會覆蓋類中的設定。
                if(isMethondAnnotation){
                    rc=m.getAnnotation(RoleControl.class);
                }else if(isClzAnnotation){
                    rc=classz.getAnnotation(RoleControl.class);
                }
                String value=rc.value();
                Object obj=session.getAttribute(GeneUtil.SESSION_USERTYPE_KEY);
                String curUserType=obj==null?"":obj.toString();
                //進行角色訪問的權限控制,只有當前用戶是需要的角色才予以訪問。
                boolean isEquals=StringUtils.checkEquals(value, curUserType);
                if(isEquals){
                    try {
                        return point.proceed();
                    } catch (Throwable e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

            }
        }catch(Exception e){

        }
        return null;
    }
}

方式二:使用攔截器,推薦    

import java.lang.reflect.Method;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import net.xby1993.springmvc.annotation.RoleControl;
import net.xby1993.springmvc.util.GeneUtil;
import net.xby1993.springmvc.util.PathUtil;
import net.xby1993.springmvc.util.StringUtils;

public class GlobalInterceptor extends HandlerInterceptorAdapter{
    private static Logger log=LoggerFactory.getLogger(LoginInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        HttpSession s=request.getSession();
        s.setAttribute("host", PathUtil.getHost());
        s.setAttribute("siteName", GeneUtil.SITE_NAME);
        //角色權限控制訪問
        return roleControl(request,response,handler);
    }
    /**角色權限控制訪問*/
    private boolean roleControl(HttpServletRequest request,HttpServletResponse response, Object handler){
        HttpSession session=request.getSession();
        System.out.println(handler.getClass().getName());
        if(handler instanceof HandlerMethod){
            HandlerMethod hm=(HandlerMethod)handler;
            Object target=hm.getBean();
            Class<?> clazz=hm.getBeanType();
            Method m=hm.getMethod();
            try {
                if (clazz!=null && m != null ) {
                    boolean isClzAnnotation= clazz.isAnnotationPresent(RoleControl.class);
                    boolean isMethondAnnotation=m.isAnnotationPresent(RoleControl.class);
                    RoleControl rc=null;
                    //如果方法和類聲明中同時存在這個注解,那么方法中的會覆蓋類中的設定。
                    if(isMethondAnnotation){
                        rc=m.getAnnotation(RoleControl.class);
                    }else if(isClzAnnotation){
                        rc=clazz.getAnnotation(RoleControl.class);
                    }
                    String value=rc.value();
                    Object obj=session.getAttribute(GeneUtil.SESSION_USERTYPE_KEY);
                    String curUserType=obj==null?"":obj.toString();
                    //進行角色訪問的權限控制,只有當前用戶是需要的角色才予以訪問。
                    boolean isEquals=StringUtils.checkEquals(value, curUserType);
                    if(!isEquals){
                        //401未授權訪問
                        response.setStatus(401);
                        return false;
                    }
                }
            }catch(Exception e){

            }
        }

        return true;
    }

}
 本文由用戶 vqfq6057 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!