How thymeleaf processes value of "sec:authorize" attribute (Spring Security integration module)
Tags: spring, thymeleaf, springmvc
Published: 2024-02-11 13:48:54

## Notice

I wrote this article and was originally published on [Qiita](https://qiita.com/saladlam/items/a611787e817118c78a1d) on 3 September 2019.

---

# Package used
- spring-webmvc-5.1.9.RELEASE
- thymeleaf-3.0.11.RELEASE
- thymeleaf-spring5-3.0.11.RELEASE
- thymeleaf-extras-springsecurity5-3.0.4.RELEASE

# How?

First look into following code which extract from [guide from thymeleaf](https://www.thymeleaf.org/doc/articles/springsecurity.html).

```html
<div sec:authorize="isAuthenticated()">
  This content is only shown to authenticated users.
</div>
<div sec:authorize="hasRole('ROLE_ADMIN')">
  This content is only shown to administrators.
</div>
<div sec:authorize="hasRole('ROLE_USER')">
  This content is only shown to users.
</div>
```

## Attribute value of "sec:authorize" is handle by class org.thymeleaf.extras.springsecurity5.dialect.processor.AuthorizeAttrProcessor

```java
public final class AuthorizeAttrProcessor extends AbstractStandardConditionalVisibilityTagProcessor {

    @Override
    protected boolean isVisible(
            final ITemplateContext context, final IProcessableElementTag tag,
            final AttributeName attributeName, final String attributeValue) {

        final String attrValue = (attributeValue == null? null : attributeValue.trim());

        if (attrValue == null || attrValue.length() == 0) {
            return false;
        }

        final Authentication authentication = AuthUtils.getAuthenticationObject(context);

        if (authentication == null) {
            return false;
        }

        return AuthUtils.authorizeUsingAccessExpression(context, attrValue, authentication);

    }
    // ...
}
```

## Attribute value of "sec:authorize" will be processed by SpEL

This code

```html
<div sec:authorize="isAuthenticated()">
  This content is only shown to authenticated users.
</div>
```

have the same meaning of

```html
<div sec:authorize="${isAuthenticated()}">
  This content is only shown to authenticated users.
</div>
```

due to text between brackets will be extract by org.thymeleaf.extras.springsecurity5.auth.AuthUtils.MvcAuthUtils.authorizeUsingAccessExpressionMvc(IExpressionContext, String, Authentication) before pass to SpEL.

```java
    private static final class MvcAuthUtils {

        private static boolean authorizeUsingAccessExpressionMvc(
                final IExpressionContext context,
                final String accessExpression, final Authentication authentication) {

            /*
             * In case this expression is specified as a standard variable expression (${...}), clean it.
             */
            final String expr =
                    ((accessExpression != null && accessExpression.startsWith("${") && accessExpression.endsWith("}"))?
                            accessExpression.substring(2, accessExpression.length() - 1) :
                            accessExpression);
            // ...

            // pass to SpEL
            return (ExpressionUtils.evaluateAsBoolean(expressionObject, wrappedEvaluationContext));
        }
        // ...
    }
```

## isAuthenticated() and hasRole() is function of class org.springframework.security.web.access.expression.WebSecurityExpressionRoot

EvaluationContext used by SpEL is build from org.springframework.security.access.expression.AbstractSecurityExpressionHandler.createEvaluationContext(Authentication, T).

```java
public abstract class AbstractSecurityExpressionHandler<T> implements
		SecurityExpressionHandler<T>, ApplicationContextAware {

	public final EvaluationContext createEvaluationContext(Authentication authentication,
			T invocation) {
		SecurityExpressionOperations root = createSecurityExpressionRoot(authentication,
				invocation);
		StandardEvaluationContext ctx = createEvaluationContextInternal(authentication,
				invocation);
		ctx.setBeanResolver(br);
		ctx.setRootObject(root);

		return ctx;
	}

    // ...
}
```

Variable "root" is instance of class org.springframework.security.web.access.expression.WebSecurityExpressionRoot.