spring security 的@Secured 标注在Controller上

创建SecuredInterceptor类继承HandlerInterceptorAdapter类

重写preHandle方法

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if(getLoginUrl() != null && request.getUserPrincipal() == null) { throw new ModelAndViewDefiningException(new ModelAndView("redirect:" + getLoginUrl())); } try { ServletHandlerMethodResolver methodResolver = getMethodResolver(handler); Method handlerMethod = methodResolver.resolveHandlerMethod(request); String[] secureds = getMethodSecured(handlerMethod); if(secureds == null) { return true; } if (logger.isDebugEnabled()) { logger.debug("[" + handlerMethod.getDeclaringClass() + "] method:[" + handlerMethod.getName() + "] role:" + Arrays.asList(secureds)); } for(String secured : secureds) { if(!request.isUserInRole(secured)) { if(getDenyUrl() != null) { throw new ModelAndViewDefiningException(new ModelAndView("redirect:" + getDenyUrl())); } response.sendError(HttpServletResponse.SC_FORBIDDEN,secured); return false; } } return true; } catch (NoSuchRequestHandlingMethodException ex) { response.sendError(HttpServletResponse.SC_NOT_FOUND); return false; } }

创建 RequestMappingInfo 类 重写equals和hashCode方法

private static class RequestMappingInfo { public String[] paths = new String[0]; public RequestMethod[] methods = new RequestMethod[0]; public String[] params = new String[0]; public boolean equals(Object obj) { RequestMappingInfo other = (RequestMappingInfo) obj; return (Arrays.equals(this.paths, other.paths) && Arrays.equals(this.methods, other.methods) && Arrays .equals(this.params, other.params)); } public int hashCode() { return (Arrays.hashCode(this.paths) * 29 + Arrays.hashCode(this.methods) * 31 + Arrays .hashCode(this.params)); } }

在创建 ServletHandlerMethodResolver 类 继承HandlerMethodResolver

此类用于反射Controller类中的全部方法

private class ServletHandlerMethodResolver extends HandlerMethodResolver { public ServletHandlerMethodResolver(Class<?> handlerType) { init(handlerType); } public Method resolveHandlerMethod(HttpServletRequest request) throws ServletException { String lookupPath = urlPathHelper.getLookupPathForRequest(request); Map<RequestMappingInfo, Method> targetHandlerMethods = new LinkedHashMap<RequestMappingInfo, Method>(); Map<RequestMappingInfo, String> targetPathMatches = new LinkedHashMap<RequestMappingInfo, String>(); String resolvedMethodName = null; for (Method handlerMethod : getHandlerMethods()) { RequestMappingInfo mappingInfo = new RequestMappingInfo(); RequestMapping mapping = AnnotationUtils.findAnnotation(handlerMethod, RequestMapping.class); mappingInfo.paths = mapping.value(); if (!hasTypeLevelMapping() || !Arrays.equals(mapping.method(), getTypeLevelMapping().method())) { mappingInfo.methods = mapping.method(); } if (!hasTypeLevelMapping() || !Arrays.equals(mapping.params(), getTypeLevelMapping().params())) { mappingInfo.params = mapping.params(); } boolean match = false; if (mappingInfo.paths.length > 0) { for (String mappedPath : mappingInfo.paths) { if (isPathMatch(mappedPath, lookupPath)) { if (checkParameters(mappingInfo, request)) { match = true; targetPathMatches.put(mappingInfo, mappedPath); } else { break; } } } } else { // No paths specified: parameter match sufficient. match = checkParameters(mappingInfo, request); if (match && mappingInfo.methods.length == 0 && mappingInfo.params.length == 0 && resolvedMethodName != null && !resolvedMethodName.equals(handlerMethod.getName())) { match = false; } } if (match) { Method oldMappedMethod = targetHandlerMethods.put(mappingInfo, handlerMethod); if (oldMappedMethod != null && oldMappedMethod != handlerMethod) { if (methodNameResolver != null && mappingInfo.paths.length == 0) { if (resolvedMethodName == null) { resolvedMethodName = methodNameResolver.getHandlerMethodName(request); } if (!resolvedMethodName.equals(oldMappedMethod.getName())) { oldMappedMethod = null; } if (!resolvedMethodName.equals(handlerMethod.getName())) { if (oldMappedMethod != null) { targetHandlerMethods.put(mappingInfo, oldMappedMethod); oldMappedMethod = null; } else { targetHandlerMethods.remove(mappingInfo); } } } if (oldMappedMethod != null) { throw new IllegalStateException( "Ambiguous handler methods mapped for HTTP path '" + lookupPath + "': {" + oldMappedMethod + ", " + handlerMethod + "}. If you intend to handle the same path in multiple methods, then factor " + "them out into a dedicated handler class with that path mapped at the type level!"); } } } } if (targetHandlerMethods.size() == 1) { return targetHandlerMethods.values().iterator().next(); } else if (!targetHandlerMethods.isEmpty()) { RequestMappingInfo bestMappingMatch = null; String bestPathMatch = null; for (RequestMappingInfo mapping : targetHandlerMethods.keySet()) { String mappedPath = targetPathMatches.get(mapping); if (bestMappingMatch == null) { bestMappingMatch = mapping; bestPathMatch = mappedPath; } else { if (isBetterPathMatch(mappedPath, bestPathMatch, lookupPath) || (!isBetterPathMatch(bestPathMatch, mappedPath, lookupPath) && (isBetterMethodMatch( mapping, bestMappingMatch) || (!isBetterMethodMatch(bestMappingMatch, mapping) && isBetterParamMatch( mapping, bestMappingMatch))))) { bestMappingMatch = mapping; bestPathMatch = mappedPath; } } } return targetHandlerMethods.get(bestMappingMatch); } else { throw new NoSuchRequestHandlingMethodException(lookupPath, request.getMethod(), request .getParameterMap()); } } private boolean isPathMatch(String mappedPath, String lookupPath) { if (mappedPath.equals(lookupPath) || pathMatcher.match(mappedPath, lookupPath)) { return true; } boolean hasSuffix = (mappedPath.indexOf('.') != -1); if (!hasSuffix && pathMatcher.match(mappedPath + ".*", lookupPath)) { return true; } return (!mappedPath.startsWith("/") && (lookupPath.endsWith(mappedPath) || pathMatcher.match("/**/" + mappedPath, lookupPath) || (!hasSuffix && pathMatcher.match("/**/" + mappedPath + ".*", lookupPath)))); } private boolean checkParameters(RequestMappingInfo mapping, HttpServletRequest request) { return checkRequestMethod(mapping.methods, request) && checkParameters(mapping.params, request); } private boolean checkRequestMethod(RequestMethod[] methods, HttpServletRequest request) { if (!ObjectUtils.isEmpty(methods)) { boolean match = false; for (RequestMethod method : methods) { if (method.name().equals(request.getMethod())) { match = true; } } if (!match) { return false; } } return true; } private boolean checkParameters(String[] params, HttpServletRequest request) { if (!ObjectUtils.isEmpty(params)) { for (String param : params) { int separator = param.indexOf('='); if (separator == -1) { if (param.startsWith("!")) { if (WebUtils.hasSubmitParameter(request, param.substring(1))) { return false; } } else if (!WebUtils.hasSubmitParameter(request, param)) { return false; } } else { String key = param.substring(0, separator); String value = param.substring(separator + 1); if (!value.equals(request.getParameter(key))) { return false; } } } } return true; } private boolean isBetterPathMatch(String mappedPath, String mappedPathToCompare, String lookupPath) { return (mappedPath != null && (mappedPathToCompare == null || mappedPath.equals(lookupPath) || mappedPathToCompare .length() < mappedPath.length())); } private boolean isBetterMethodMatch(RequestMappingInfo mapping, RequestMappingInfo mappingToCompare) { return (mappingToCompare.methods.length == 0 && mapping.methods.length > 0); } private boolean isBetterParamMatch(RequestMappingInfo mapping, RequestMappingInfo mappingToCompare) { return (mappingToCompare.params.length < mapping.params.length); } }

下面是俩个内部使用的工具方法

private String[] getMethodSecured(Method handlerMethod) { String[] secureds = this.methodPrivilegeCache.get(handlerMethod); if (secureds == null) { Secured s = handlerMethod.getAnnotation(Secured.class); if(s != null) { secureds = s.value(); this.methodPrivilegeCache.put(handlerMethod, secureds); } } return secureds; } private ServletHandlerMethodResolver getMethodResolver(Object handler) { Class handlerClass = ClassUtils.getUserClass(handler); ServletHandlerMethodResolver resolver = this.methodResolverCache.get(handlerClass); if (resolver == null) { resolver = new ServletHandlerMethodResolver(handlerClass); this.methodResolverCache.put(handlerClass, resolver); } return resolver; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值