在 JavaScript 中的 Thymeleaf 中使用 Spring Security 转义表达式

Posted

技术标签:

【中文标题】在 JavaScript 中的 Thymeleaf 中使用 Spring Security 转义表达式【英文标题】:Use Spring Security in Thymeleaf escaped expressions in JavaScript 【发布时间】:2017-05-16 23:56:26 【问题描述】:

Thymeleaf 3.0 可以做到这一点:

/*[# th:if="$user.admin"]*/
    alert('Welcome admin');
/*[/]*/

但这不起作用:

/*[# sec:authorize="hasAnyRole('ROLE_ADMIN)"]*/
    alert('Welcome admin');
/*[/]*/

这真的不可能还是我做错了什么?

我使用 Spring Security 4.1。

转义表达式解析的一些背景资料:https://github.com/thymeleaf/thymeleaf/issues/395

编辑 1

Daniel Fernández 在我最初的问题中发现了一个缺失的单引号。

可惜加了之后还是不行。

表达式被解析,因为它从生成的 html/javascript 中消失了。

但是即使我没有登录,或者即使我已经登录并且我将检查更改为sec:authorize="hasRole('ROLE_ADMIN123'),也会执行 document.writeln()

<script type="text/javascript" th:inline="javascript">

    /*[# sec:authorize="hasRole('ROLE_ADMIN')"]*/
        document.writeln("ADMIN !!!");
    /*[/]*/

</script>

编辑 2

这是我的解决方法until further notice:

@Service 中创建一个方法来检查用户是否具有所需的角色:

import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Service;

@Service
public class UtilService 

    public boolean hasAnyRole(HttpServletRequest req, String... roles) 
        for (final String role : roles) 
            if (req.isUserInRole(role)) 
                return true;
            
        
        return false;
    


并在JavaScript 块中像这样使用它:

<script type="text/javascript" th:inline="javascript">

    /*[# th:if="$@utilService.hasAnyRole(#httpServletRequest, 'ROLE_ADMIN')"]*/
        ...
    /*[/]*/

</script>

【问题讨论】:

【参考方案1】:

看起来像语法错误。在您的sec:authorize="hasAnyRole('ROLE_ADMIN)"...中没有您的角色名称的结束引号...

【讨论】:

确实如此。今晚晚些时候我会检查并告诉你。谢谢! 顺便说一句,显示问题的演示应用程序在这里:github.com/yglodt/spring-boot-thymeleaf 在demo-app中,链接“page3”需要认证。 好的,SpringSecurity 方言似乎没有为文本模式(JAVASCRIPT、CSS、TEXT)注册其处理器,这样做似乎是个好主意(它们目前仅可用于 HTML )。请在 Thymeleaf - Spring Security 方言的 GitHub 问题系统上注册?【参考方案2】:

我遇到了同样的问题 我只需要更新 thymeleaf 和 thymeleaf-extras-springsecurity4 就可以了。

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <thymeleaf.version>3.0.3.RELEASE</thymeleaf.version>
    <thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version>
</properties>

这里是a link

【讨论】:

【参考方案3】:

如果您希望控制哪个用户或组可以访问特定的 JS 文件而不是编写内联 JS,您可以随时在脚本标签中添加 sec:authorize 键。通过这种方式,您可以将字段、功能和数据封装给一组给定的用户,并在整个项目中保持对模板的务实使用。

在这种情况下,我使用 hasAuthority 参数,因为当用户登录我的 Web 应用程序时,我已将组声明附加到我的 JWT。您显然可以定制它以满足您自己的需求。使用 Spring5 和 thymeleaf 3 测试和工作。

这就是我在你的 HTML 中的意思。

   <html xmlns:th="http://thymeleaf.org" xmlns="http://www.w3.org/1999/html" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
    <body></body>
    <script type="text/javascript" th:src="@/js/myJsFile.js" sec:authorize="$hasAuthority('usersGroup')"></script>
    <script type="text/javascript" th:src="@/js/myOtherJsFile.js" sec:authorize="$hasAuthority('adminGroup')"></script>

这是我的 POM 依赖项:

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity5</artifactId>
    <version>3.0.4.RELEASE</version>
</dependency>

我特别希望这样做是为了限制对特定数据库字段的访问以编辑表格。 https://editor.datatables.net/manual/security#Privilege-escalation

完整参考:https://www.thymeleaf.org/doc/articles/springsecurity.html

【讨论】:

以上是关于在 JavaScript 中的 Thymeleaf 中使用 Spring Security 转义表达式的主要内容,如果未能解决你的问题,请参考以下文章

带引号的Thymeleaf内联javascript不起作用

SpringBoot——Thymeleaf中的th:inline(内敛文本text内敛脚本javascript)

SpringBoot——Thymeleaf中的th:inline(内敛文本text内敛脚本javascript)

thymeleaf

Thymeleaf 将 JSON 字符串作为 JSON 对象打印到 javascript 变量中

在 thymeleaf 中包含 JavaScript 变量