SpringSecurity hasRole()的原理(拼装ROLE_与不拼装ROLE_的效果相同)

介绍

在配置类中,url的权限控制方法hasRole()和hasAnyRole(),传入的角色字符串,前面拼装ROLE_与不拼装ROLE_的效果相同

原因是: 在SecurityExpressionRoot类中,做了处理,关键代码

定义前缀

private String defaultRolePrefix = "ROLE_";

hasRole()、hasAnyRole()源码

    public final boolean hasRole(String role) {
        return this.hasAnyRole(role);
    }

    public final boolean hasAnyRole(String... roles) {
        return this.hasAnyAuthorityName(this.defaultRolePrefix, roles);
    }

    private boolean hasAnyAuthorityName(String prefix, String... roles) {
        Set<String> roleSet = this.getAuthoritySet();
        String[] var4 = roles;
        int var5 = roles.length;

        for(int var6 = 0; var6 < var5; ++var6) {
            String role = var4[var6];
            String defaultedRole = getRoleWithDefaultPrefix(prefix, role);
            if (roleSet.contains(defaultedRole)) {
                return true;
            }
        }

        return false;
    }

调用hasRole()方法,就是在调用hasAnyRole()方法
调用hasAnyRole()方法,就是在调用hasAnyAuthorityName()方法,并传入了前缀

getRoleWithDefaultPrefix()方法源码如下,如果没有前缀ROLE_,就拼装上前缀ROLE_:

private static String getRoleWithDefaultPrefix(String defaultRolePrefix, String role) {
        if (role == null) {
            return role;
        } else if (defaultRolePrefix != null && defaultRolePrefix.length() != 0) {
            return role.startsWith(defaultRolePrefix) ? role : defaultRolePrefix + role;
        } else {
            return role;
        }
    }

总结:

所以,hasRole()和hasAnyRole(),传入的角色字符串,前面拼装ROLE_与不拼装ROLE_的效果相同