Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Freemarker JSPTaglib issue while upgrading to Spring Boot 3 and java 17

When I initially started migrating from Spring MVC to Spring Boot 2 I was facing issue related freemarker JspTagLib That got solved by doing some workaround.

<#assign security=JspTaglibs["http://www.springframework.org/security/tags"]/>

<@security.authorize access="isAuthenticated()">
    <@security.authentication property="principal.username"/>
</@security.authorize>

Referred: https://vorba.ch/2018/spring-boot-freemarker-security-jsp-taglib.html

Above code is working fine Spring Boot 2

Now I am upgrading Spring Boot 3 then its not working. Thing which I have added for working in Spring Boot 2, In Boot 3 class field(TaglibFactory) removed.

freeMarkerConfigurer.getTaglibFactory().setClasspathTlds(…);

Could you please help here?

like image 446
Shyam Avatar asked Sep 13 '25 23:09

Shyam


2 Answers

I had this problem upgrading an old project from Spring 3 to Spring 6, by now we have no time to replace the technology used to render the views, and the last version of FreeMarkerConfigurer does not provide the method getTaglibFactory:

  • FreeMarkerConfigurer (Spring 5)
  • FreeMarkerConfigurer (Spring 6)

So my solution for JSP security tags was rewrite them using FreeMarker macros:

<#ftl output_format="HTML" strip_whitespace=true> 
<#-- 
 * security.ftl 
 * 
 * This file consists of a collection of FreeMarker macros aimed at easing 
 * some of the common requirements of web applications - in particular 
 * handling of security. 
--> 
 
<#-- 
 * isAnonymous 
 * 
 * Verifies if there is no a logged user.
--> 
<#macro isAnonymous> 
  <#assign anonymous = true> 
  <#if SPRING_SECURITY_CONTEXT??> 
    <#assign anonymous = false> 
  </#if> 
  <#if anonymous> 
    <#nested> 
  </#if> 
</#macro> 
 
 
<#-- 
 * isAuthenticated 
 * 
 * Checks if there is a logged user and he/she is authenticated. 
--> 
<#macro isAuthenticated> 
  <#assign authenticated = false> 
  <#if SPRING_SECURITY_CONTEXT??> 
    <#assign authentication = SPRING_SECURITY_CONTEXT.authentication
              isUserAuthenticated = authentication.isAuthenticated()> 
    <#if isUserAuthenticated> 
      <#assign authenticated = true> 
    </#if> 
  </#if> 
  <#if authenticated> 
    <#nested> 
  </#if> 
</#macro>


<#-- 
 * hasRole 
 * 
 * Verifies if there is a logged user and he/she has the given role/authority.
 * 
 * Example: 
 * 
 *   <@security.hasRole role="ROLE_ADMIN"> 
 *     <br><span>User has the role: ROLE_ADMIN</span> 
 *   </@security.hasRole> 
 * 
 * @param role 
 *    The role and/or authority to verify 
--> 
<#macro hasRole role> 
  <#assign authorized = false> 
  <#if SPRING_SECURITY_CONTEXT?? && role??> 
    <#list SPRING_SECURITY_CONTEXT.authentication.authorities as authority> 
      <#if authority == role> 
        <#assign authorized = true> 
      </#if> 
    </#list> 
  </#if> 
  <#if authorized> 
    <#nested> 
  </#if> 
</#macro>
 
 
<#-- 
 * ifAnyGranted 
 * 
 * Checks if there is a logged user and he/she has one of the given roles/authorities. 
 * 
 * Example: 
 * 
 *   <@security.ifAnyGranted roles="ROLE_ADMIN,ROLE_SUPERADMIN"> 
 *     <br><span>User has one of the roles: ROLE_ADMIN, ROLE_SUPERADMIN</span> 
 *   </@security.ifAnyGranted> 
 * 
 * @param roles 
 *    Roles and/or authorities separated by commas to verify 
--> 
<#macro ifAnyGranted roles> 
  <#assign authorized = false> 
  <#if SPRING_SECURITY_CONTEXT?? && roles??> 
    <#list SPRING_SECURITY_CONTEXT.authentication.authorities as authority> 
      <#list roles?split(",") as role> 
        <#if authority == role> 
          <#assign authorized = true> 
        </#if> 
      </#list> 
    </#list> 
  </#if> 
  <#if authorized> 
    <#nested> 
  </#if> 
</#macro>


<#--
 * ifNotGranted
 *
 * Checks if there is a logged user and he/she does not have any of the given roles/authorities.
 *
 * Example:
 *
 *   <@security.ifNotGranted roles="ROLE_ADMIN,ROLE_SUPERADMIN">
 *      <br><span>User does not have any of the roles: ROLE_ADMIN, ROLE_SUPERADMIN</span>
 *   </@security.ifNotGranted>
 *
 * @param roles
 *    Roles and/or authorities separated by commas to verify
 -->
<#macro ifNotGranted roles>
    <#assign authorized = false>
    <#if SPRING_SECURITY_CONTEXT?? && roles??>
        <#assign authorized = true>
        <#list SPRING_SECURITY_CONTEXT.authentication.authorities as authority>
            <#list roles?split(",") as role>
                <#if authority == role>
                    <#assign authorized = false>
                </#if>
            </#list>
        </#list>
    </#if>
    <#if authorized>
        <#nested>
    </#if>
</#macro>

I added it to the file security.ftl and import it in a common ftl file using:

<#import "security.ftl" as security />

I think the reason for spring to remove getTaglibFactory() is that freemarker 2.3.32 use the javax namespace not the Jakarta EE Namespace. It exist an resolved issue for that FREEMARKER-218. It is solved but it is unknown then version 2.3.33 is released. Maybe then spring brings the getTaglibFactory() method back.

like image 27
mwowc Avatar answered Sep 15 '25 14:09

mwowc