Spring Security使用通配符授权访问角色

时间:2011-09-07 16:07:57

标签: spring-security

我是否可以在<sec:authorize />标记的access属性中使用通配符。

目前我有     <sec:authorize access="hasRole('TICKET_VIEW') or hasRole('TICKET_EDIT')">

但我希望能够使用     <sec:authorize access="hasRole('TICKET_*')">

这是可能的,还是有人知道可以完成同样的事情?

由于

2 个答案:

答案 0 :(得分:6)

Spring EL中可以从Spring 3.x开始。您正在寻找的表达式为hasAnyRole(..)

所以看起来应该是这样的:

<sec:authorize access="hasAnyRole('TICKET_VIEW', 'TICKET_EDIT')">
    ...
</sec:authorize>

这是一些更多Spring EL表达式的链接: http://static.springsource.org/spring-security/site/docs/3.0.x/reference/el-access.html

答案 1 :(得分:3)

我意识到这是一个老问题,但这个答案可能有助于未来的搜索者。

1)允许固定集中的单个角色:这是一个简单的基本情况。

<security:authorize access="hasRole('ROLE_ADMIN_ABC')">
    You are allowed to see these admin links.
</security:authorize>

2)允许来自固定集的任何角色:对于您想要允许“任何以ADMIN开头的角色”的情况,您事先知道所有角色名称,而您只是拥有一些角色,jzelenkov的回答是完全正确的。但是,如果要处理的角色太多,您可能希望创建一个可以进行访问决策的自定义方法调用,并使用SpEL将其插入到访问属性中。此解决方案更接近最初提出的通配符问题。

<bean id="mySecurityBean" class="com.sample.MySecurityBean" />

<security:authorize access="@mySecurityBean.roleStartsWith(principal, 'ROLE_ADMIN_')">
    You are allowed to see these admin links.
</security:authorize>

public class MySecurityBean {
    /**
     * Returns true if any role starts with some prefix.
     */
    public boolean roleStartsWith(UserDetails user, String rolePrefix) {
        for (GrantedAuthority auth : user.getAuthorities()) {
            if (auth.getAuthority().startsWith(rolePrefix)
                return (true);
        }
        return (false);
    }
}

3)允许来自动态集的单个角色:对于您希望允许“以ADMIN开头的特定角色”的情况,但您不一定知道所有允许的角色后缀,您可以在渲染时使用JSTL插入角色名称。例如,考虑一个具有许多工作空间的应用程序,每个工作区都有唯一的代码。您想为每个工作区创建一个ROLE_ADMIN_workspaceName角色。当有人访问ABC工作区页面时,您只希望在用户具有ROLE_ADMIN_ABC角色时显示管理员链接。让我们假设每个工作空间使用相同的JSP视图,并将名称作为$ {workspaceName}传递给模型。

<sec:authorize access="hasRole('ROLE_ADMIN_${workspaceName}')">
    You are allowed to see these admin links.
</sec:authorize>

4)允许动态集中的任何角色:这与#2的解决方案相同。