DEV Community

Salad Lam
Salad Lam

Posted on

How thymeleaf processes value of "sec:authorize" attribute (Spring Security integration module)

Notice

I wrote this article and was originally published on Qiita 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.

<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> 
Enter fullscreen mode Exit fullscreen mode

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

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); } // ... } 
Enter fullscreen mode Exit fullscreen mode

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

This code

<div sec:authorize="isAuthenticated()"> This content is only shown to authenticated users. </div> 
Enter fullscreen mode Exit fullscreen mode

have the same meaning of

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

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

 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)); } // ... } 
Enter fullscreen mode Exit fullscreen mode

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).

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; } // ... } 
Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)