Thymeleaf 和 Spring Security - 自定义 SpEL 表达式

Posted

技术标签:

【中文标题】Thymeleaf 和 Spring Security - 自定义 SpEL 表达式【英文标题】:Thymelaf and Spring Security - custom SpEL expression 【发布时间】:2018-06-09 21:14:42 【问题描述】:

我将 Thymeleaf 与 Spring Security 一起使用。 在 html 代码中,我正在检查用户角色:

<li class="has-sub" sec:authorize="hasRole('ROLE_ADMIN')"> 
</li>

但是在春天我实现了自己的CustomSecurityExpressionRoot,所以我可以在控制器中使用例如

@PreAuthorize("hasAccess('PERMISSION')")

可以连接 Thymeleaf 以使用我的CustomSecurityExpressionRoot 中的hasAccess(和其他)方法吗?

【问题讨论】:

【参考方案1】:

我会把逻辑放在一个单独的 Spring bean 中:

@Component
public class AccessEvaluator 
    public boolean hasAccess(Authentication authentication, String permission) 
        // implementation
    

然后在 Thymeleaf 代码中:

<li th:if="$@accessEvaluator.hasAccess(#request.userPrincipal, 'PERMISSION')"> 
</li>

【讨论】:

这是正确答案。该想法的唯一缺点是 multimpe hasAccess 实现(用于 Thymeleaf 和 spring [控制器等]) 为什么需要多个实现?您可以在两个位置使用相同的。他们都执行表达式,应该没有任何区别。这里提到的其实也是 Spring Security Team 推荐的方法,实现和连接自定义安全表达式根变得更加困难,有利于这种方法。【参考方案2】:

我使用与发布的答案类似的方法来获得身份验证:

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

@Component
public class AccessEvaluator 

    public boolean hasAccess(String pageName) 
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        return ((MyUserPrincipal) auth.getPrincipal()).getAccessOnPage(pageName);
    


并调用如下:

<li th:if="$@accessEvaluator.hasAccess('ACT')" >
    <p> I have access on ACT page </p>
</li>

【讨论】:

以上是关于Thymeleaf 和 Spring Security - 自定义 SpEL 表达式的主要内容,如果未能解决你的问题,请参考以下文章

Thymeleaf模板引擎+Spring整合使用方式的介绍

Spring Boot 和 Thymeleaf:链接列表

混合前端和服务器端技术(Spring、Thymeleaf、AngularJS)

Thymeleaf 和 Spring 引导以及 Spring 安全性不起作用

Spring Boot中使用thymeleaf

spring mvc 整合jsp和thymeleaf两个模板引擎