Thymeleaf exception handling Calling methods is forbidden for type

Version

thymeleaf 3.0.15

Phenomenon

An error is reported when getting the exception message through ${session.SPRING_SECURITY_LAST_EXCEPTION.getMessage()} in the thymeleaf template

Caused by: org.springframework.expression.EvaluationException: Calling methods is forbidden for type ‘java.lang.RuntimeException’ in Thymeleaf expressions. Blacklisted classes are: [java.util.concurrent.RunnableFuture, java.util.concurrent.Executor, java.lang.Runtime, java.util.concurrent.FutureTask, java.util.concurrent.ListenableFuture, java.lang.Runnable, java.util.concurrent.Future, java.lang.Thread, java.lang.reflect.Executable, java.lang.Class, java.lang.ClassLoader, java.sql.DriverManager].

reason

In thymeleaf 3.0.15, classes prefixed with java.lang.Runtime are blacklisted and not allowed to be accessed in templates

solve

Exceptions should be thrown as Exception instead of RuntimeException, other similar problems can be solved

source code

  • package thymeleaf-spring5-3.0.15

org.thymeleaf.spring5.expression.ThymeleafEvaluationContext

static final class ThymeleafEvaluationContextACLMethodResolver extends ReflectiveMethodResolver {
    
    

        ThymeleafEvaluationContextACLMethodResolver() {
    
    
            super();
        }

        @Override
        public MethodExecutor resolve(
                final EvaluationContext context, final Object targetObject,
                final String name, final List<TypeDescriptor> argumentTypes) throws AccessException {
    
    

            final Class<?> type = (targetObject instanceof Class ? (Class<?>) targetObject : targetObject.getClass());
            // 判断对象是否时允许访问的类型
            if (!ExpressionUtils.isTypeAllowed(type.getName())) {
    
    
                // We will only specifically allow calling "Object.getClass()" and "Class.getName()"
                if (!(Class.class.equals(type) && "getName".equals(name))
                        && !(Object.class.equals(type) && "getClass".equals(name))) {
    
    
                    throw new EvaluationException(
                            String.format(
                                    "Calling methods is forbidden for type '%s' in Thymeleaf expressions. " +
                                    "Blacklisted classes are: %s.",
                                    type.getName(), ExpressionUtils.getBlacklist()));
                }
            }
            return super.resolve(context, targetObject, name, argumentTypes);
        }

    }
  • 包thymeleaf-3.0.15
    org.thymeleaf.util. ExpressionUtils
public final class ExpressionUtils {
    
    
	// 所有黑名单类名前缀
    private static final Set<String> BLOCKED_CLASS_NAME_PREFIXES =
            new HashSet<String>(Arrays.asList(
                    "java.lang.Runtime", "java.lang.Thread", "java.lang.Class", "java.lang.ClassLoader",
                    "java.lang.Runnable", "java.lang.reflect.Executable",
                    "java.util.concurrent.Future", "java.util.concurrent.FutureTask",
                    "java.util.concurrent.RunnableFuture", "java.util.concurrent.ListenableFuture",
                    "java.util.concurrent.Executor",
                    "java.sql.DriverManager"));

    public static boolean isTypeAllowed(final String typeName) {
    
    
        Validate.notNull(typeName, "Type name cannot be null");
        final int i0 = typeName.indexOf('.');
        if (i0 >= 0) {
    
    
            final String package0 = typeName.substring(0, i0);
            if ("java".equals(package0)) {
    
     // This is the only prefix that might be blocked
                for (final String prefix : BLOCKED_CLASS_NAME_PREFIXES) {
    
    
                    if (typeName.startsWith(prefix)) {
    
    
                        return false;
                    }
                }
            }
        }
        return true;
    }
    public static List<String> getBlockedClasses() {
    
    
        final List<String> blocked = new ArrayList<String>();
        blocked.addAll(BLOCKED_CLASS_NAME_PREFIXES);
        return blocked;
    }
    private ExpressionUtils() {
    
    
        super();
    }
}

Guess you like

Origin blog.csdn.net/zhoudingding/article/details/130364149