Spring Security 3.2.7 HttpServletRequest.isUserInRole(String) 不会自动添加"ROLE_"前缀

Spring Security 3.2.7 HttpServletRequest.isUserInRole(String) does not automatically add "ROLE_" prefix

我正在研究 Spring 安全性并且我正在使用 Spring 安全性 3.2.7 并且对 servlet 集成功能有疑问

参考 Spring 文档

3.1.3. HttpServletRequest.isUserInRole(String)

The HttpServletRequest.isUserInRole(String) will determine if SecurityContextHolder.getContext().getAuthentication().getAuthorities() contains a GrantedAuthority with the role passed into isUserInRole(String).

Typically users should not pass in the "ROLE_" prefix into this method since it is added automatically. For example, if you want to determine if the current user has the authority "ROLE_ADMIN", you could use the the following:

boolean isAdmin = httpServletRequest.isUserInRole("ADMIN");

This might be useful to determine if certain UI components should be displayed. For example, you might display admin links only if the current user is an admin.

然而,当我尝试时,我发现 httpServletRequest.isUserInRole("ADMIN"); return 假,而 httpServletRequest.isUserInRole("ROLE_ADMIN"); return 正确。

是否有任何特殊配置要求在调用 isUserInRole 时自动添加 "ROLE_" 前缀?

以下是我的配置(来自示例应用程序)

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />
            <user name="bob" password="bobspassword" authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>

我已经找到了解决办法。通过比较 class org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestWrapper Spring Security 3.2.7 和 4.0.1 之间的源代码,我发现在 4.0.1 中 属性 rolePrefix 初始化为值 "ROLE_" 但不是在 3.2.7.

Spring 安全 3.2.7

private final String rolePrefix;

Spring 安全 4.0.1

private String rolePrefix = "ROLE_";

因此 "ROLE_" 前缀似乎没有自动添加到 Spring Security 3.2.7

并且使用 Migrating from Spring Security 3.x to 4.x (XML Configuration) 中的示例,我创建了一个 BeanPostProcessor 以将 "ROLE_" 设置为 SecurityContextHolderAwareRequestFilter 的 rolePrefix 属性。

public class DefaultRolesPrefixPostProcessor implements BeanPostProcessor, PriorityOrdered {

    ...

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        if (bean instanceof SecurityContextHolderAwareRequestFilter) {
            SecurityContextHolderAwareRequestFilter filter = (SecurityContextHolderAwareRequestFilter) bean;
            filter.setRolePrefix("ROLE_");
        }
        return bean;
    }
}

以上解决方案适用于我的情况,但我不确定这是否是正确的方法。