创建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 {
-
- 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;
- }