Spring @PreAuthorize hasAuthority 异常无法从类型 [java.lang.String] 转换为类型 [java.lang.Boolean] 的值'hasAuthori

Posted

技术标签:

【中文标题】Spring @PreAuthorize hasAuthority 异常无法从类型 [java.lang.String] 转换为类型 [java.lang.Boolean] 的值\'hasAuthority【英文标题】:Spring @PreAuthorize hasAuthority Exception Failed to convert from type [java.lang.String] to type [java.lang.Boolean] for value 'hasAuthoritySpring @PreAuthorize hasAuthority 异常无法从类型 [java.lang.String] 转换为类型 [java.lang.Boolean] 的值'hasAuthority 【发布时间】:2020-12-19 17:16:22 【问题描述】:

所以我用两个简单的公共字符串创建了一个类

public final class Right 
    private Right() 
        super();
    

    public static final String AUTH = "hasAuthority('admin') or hasAuthority('mod')";


当我将它与控制器上的 @PreAuthorize 注释一起使用时,它就像一个魅力。我不喜欢它是硬编码的。出于这个原因,我将角色放在属性中,并尝试将其用作组件:

@Component("authRule")
public class AuthRule 

    @Value("$role.administrator")
    private String roleAdmin;

    @Value("$role.moderator")
    private String roleMod;

    public String getRightAccess() 
        return "hasAuthority('" + roleAdmin+ "')" + " or hasAuthority('" + roleMod+ "')";
    

当我在我的 PreAuthorize 中使用它时:

@PreAuthorize("@authRule.getRightAccess()")

我正在返回一个异常,即 Failed to convert from type [java.lang.String] to type [java.lang.Boolean] for value 'hasAuthority('admin') or hasAuthority('mod')

如果我在 PreAuthorize 中硬编码。我对此感到很困惑。有人有什么想法吗?

提前感谢所有回复。

【问题讨论】:

【参考方案1】:

我快速阅读了文档; https://docs.spring.io/spring-security/site/docs/current/reference/html5/#el-pre-post-annotations

提供给注解的值很可能只被解析一次。我认为你需要它解析两次;一次触发您的自定义组件的方法 getRightAccess()。第二次解析该方法返回的字符串结果。如果您对“布尔”进行一般搜索,这里有一些示例; https://docs.spring.io/spring/docs/4.3.10.RELEASE/spring-framework-reference/html/expressions.html

// evaluates to true
boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(
        societyContext, Boolean.class);

所以你的 getRightAccess() 方法中可能需要这样的东西;

return parser.parseExpression("hasAuthority('"+roleAdmin+"') or hasAuthority('"+roleMod+"')").getValue(Boolean.class);

【讨论】:

@PreAuthorize 接受一个字符串值并使用 SPRING EL 表达式将其转换为布尔值 h​​asAuthority 或 hasRole 很常见。正如我在文章开头提到的那样,它就像静态字符串的魅力一样,但当我从属性中检索它们时就不行了。 我明白了。我已经更新了我的答案。抱歉,我帮不上忙,我以前没有使用过 Spring Security 的东西。 我使用了您的新答案,但效果不佳。尽管如此,它还是帮助我深入研究了 SPEL 解析器及其解决方案。我发现我可以在 @PreAuthorize 中传递任何自定义布尔值,因此我创建了自己的方法并传递了它,它可以工作。可悲的是,当我们必须使用预定义的诸如 hasAuthority 时,您需要一个常量表达式。但再次感谢您。 hasAuthorityhasRole 方法在哪里? 在这里试试docs.spring.io/spring-security/site/docs/5.1.x/reference/…

以上是关于Spring @PreAuthorize hasAuthority 异常无法从类型 [java.lang.String] 转换为类型 [java.lang.Boolean] 的值'hasAuthori的主要内容,如果未能解决你的问题,请参考以下文章

spring @Preauthorize 中的自定义方法

Spring Security @PreAuthorize 拦截无效

Spring Security SAML 扩展和@PreAuthorize

Spring @Secured 和 @PreAuthorize 不能正常工作(总是状态 403)

使用 @PreAuthorize 时从 Spring 控制器返回 405 与 403

spring security 3 中的@Secured 和@PreAuthorize 有啥区别?