I wonder why spring doesn't directly evaluate all expressions as they are injected from a property file into @PreAuthorize(...)
annotation. I think spring doesn't evaluate some characters like '(', ')', ''', etc or it adds special characters on top of those injected values from property file. To clarify, let us consider the following example.
@PreAuthorize("hasRole('ROLE_ADMIN')")
The above expression is normal, and works fine. Suppose values of the property file are the following.
role1=ROLE_ADMIN
role2='ROLE_ADMIN'
role3=hasRole('ROLE_ADMIN')
Let us inject role1
from property file and pass it to @PreAuthorize("hasRole(${role1})")
, it works fine. In normal way of evaluating hasRole(...)
expression, the role name must be under single quotes, i.e, 'ROLE_ADMIN'
. But here it works with ROLE_ADMIN. Surprising!.
If we inject role2
from property file into @PreAuthorize("hasRole(${role2})")
, it returns access denied. That means it is evaluated but we can realise that the value passed to the expression is something other than "'ROLE_ADMIN'
". So, if the role name is under single quotes, access is denied. Another surprise!.
If we try to inject role3
from a property file into @PreAuthorize("${role3}")
, it is not being evaluated as well.
exceptions:
java.lang.IllegalArgumentException: Failed to evaluate expression 'role3'
with root causes:
org.springframework.expression.spel.SpelEvaluationException: EL1001E:(pos 0): Type conversion problem, cannot convert from java.lang.String to java.lang.Boolean
java.lang.IllegalArgumentException: Invalid boolean value 'hasRole('ROLE_ADMIN')'
My conclusion:
From (1) and (2) above, we may realise one thing. That is, it seems that injected values are placed under single quotes (' ') when being passed to the @PreAuthorize(...)
annotation. If this statement is not true, (1) and (2) wouldn't be working. Its just my conclusion!.
When we come to (3), the case seems similar to (1) and (2). The value in the file is "hasRole('ROLE_ADMIN')
". After injecting this value correctly, if single quotes are added while passing to the @PreAuthorize(...)
, it will be like @PreAuthorize("'hasRole('ROLE_ADMIN')'")
. So "'hasRole('ROLE_ADMIN')'
" is a string not a boolean value. Its just my suspect.
Question:
Do you think that my conclusion is correct? if not, can you point out me if there is something that I've missed? Or provide me if you have alternative solutions to achieve @PreAuthorize(...)
by injecting values from property file.
Thank you in advance!
Note
: it is neither a problem of configuration nor injection. I checked that the values are correctly injected.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…