6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

どうやってthymeleafが属性"sec:authorize"を処理する(Spring Security整合するモジュール)

Last updated at Posted at 2019-09-03

使ったパッケージ

  • spring-webmvc-5.1.9.RELEASE
  • thymeleaf-3.0.11.RELEASE
  • thymeleaf-spring5-3.0.11.RELEASE
  • thymeleaf-extras-springsecurity5-3.0.4.RELEASE

どうやって?

まず以下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>

属性"sec:authorize"はクラス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);

    }
    // ...
}

属性"sec:authorize"がSpELで処理される

以下のコード

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

は以下のコードと同じ意味

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

理由はメソッドorg.thymeleaf.extras.springsecurity5.auth.AuthUtils.MvcAuthUtils.authorizeUsingAccessExpressionMvc(IExpressionContext, String, Authentication)で"${...}"なかのテキストを取り出し、それから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);
            // ...

            // SpELに通する
            return (ExpressionUtils.evaluateAsBoolean(expressionObject, wrappedEvaluationContext));
        }
        // ...
    }

isAuthenticated()とhasRole()はクラスorg.springframework.security.web.access.expression.WebSecurityExpressionRootのメソッド

SpELで使ったEvaluationContextはメソッド 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;
	}

    // ...
}

変数"root"はスラスorg.springframework.security.web.access.expression.WebSecurityExpressionRootのインスタンス。

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?