使ったパッケージ
- 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のインスタンス。