Spring Security,Permission Evaluator with intercept-url

时间:2013-12-01 00:47:39

标签: spring-mvc spring-security

我正在为自己开发小型Web应用程序,我希望用户可以获得某些操作的某些权限。我的数据库架构如下所示: 2桌:

user (id, username, password, etc...)
user_permission (id, user_id, permission (as string) )

总而言之,每个权限都可以管理一些数据(添加新员工,添加新产品等)。

我有CustomPermissionEvaluator课程(实施PermissionEvaluator)。它的相应bean是在与servlet相关的另一个.xml文件中定义的。 这是我的应用程序安全部分代码:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">

<http auto-config="true" use-expressions="true">
    <intercept-url pattern="/login" access="permitAll" />
    <intercept-url pattern="/logout" access="permitAll" />
    <intercept-url pattern="/accessdenied" access="permitAll" />
    <intercept-url pattern="/**" access="hasPermission(#user,'ROLE_USER')" />
    <form-login login-page="/login" default-target-url="/list"
        authentication-failure-url="/accessdenied" />
    <logout logout-success-url="/logout" />
</http>
<beans:bean id="customUserService" class="com.mateuszprzybyla.security.CustomUserService"></beans:bean>

<authentication-manager alias="authenticationManager">
    <authentication-provider user-service-ref="customUserService">
    </authentication-provider>
</authentication-manager>

我最近2小时努力的路线是

<intercept-url pattern="/**" access="hasPermission(#user,'ROLE_USER')" />

我需要它,以便所有未注册登录页面的用户出现。
在示例用户的数据库中,我在ROLE_USER表中拥有user_permission权限的实体。当我在没有注册的情况下进入网站时,登录页面显示,并且没关系。但是,如果我输入正确的凭据并通过授权步骤,则会显示403错误(禁止访问)。此外,在调试期间,没有调用hasPermission方法,这是我一直试图解决的问题。当我尝试将hasPermission用于单个视图部分(例如一个表)时,它可以很好地工作。

有没有人知道我的配置有什么问题,最重要的是,为什么没有调用hasPermission方法?如果您对其他课程有任何疑问,请提出要求;)

3 个答案:

答案 0 :(得分:0)

从你给出的例子来看,听起来你正在制造比他们需要的更复杂的东西。为什么不遵循加载用户角色(权限列表)和使用

的标准模式
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />

要使用hasPermission表达式,您需要使用expression-handler选项覆盖内置SecurityExpressionHandler

答案 1 :(得分:0)

public class CustomPermissionEvaluator implements PermissionEvaluator{

@Override
public boolean hasPermission(Authentication authentication,
        Object targetDomainObject, Object permission) {

    String desiredRoleName = (String) targetDomainObject;

if(authentication.isAuthenticated()) { // You don't need this 'if' block, if you have defined an anonymous ROLE for non-logged-in users in your security configuration.

    // Checking to see if the user has the roleName passed.
    for(GrantedAuthority grantedAuthority : authentication.getAuthorities()) {

        if(StringUtils.equalsIgnoreCase(grantedAuthority.getAuthority(), desiredRoleName)) {

            return true;

        } 
}
return false;

}

@Override
public boolean hasPermission(Authentication authentication,
        Serializable targetId, String targetType, Object permission) {
    throw new RuntimeException("Not Implementing this.");
}
}

我没有看到你的CustomPermissionEvaluator课程,所以很难说出你的情况出了什么问题。这是一个示例PermissionEvaluator实现。 通常,GrantedAuthority对象中的Authentication对象应具有ROLE信息,除非您使用自定义身份验证管理器。您可以调试并查看对象结构,Authentication对象应该在其中的某处包含ROLE信息。

如果您没有看到ROLE信息,您可能需要使用上面user_permission对象中的'username'在上面的代码中自己查询Authentication表,如果您使用Hibernate或任何Spring的事务数据库模板,这些注释不会绑定在上面的PermissionEvaluator类中。您最终可能会在xml配置文件中定义JDBCTemplate,并将其绑定到您的类中以查询user_permission表。

答案 2 :(得分:0)

我遇到了同样的情况。

<intercept-url pattern="/**" access="hasPermission(#user,'ROLE_USER')" />

请关注spring-docs

就我而言,

<intercept-url access="@webSecurity.checkPermission('chkValue')" pattern="/request"/>

爪哇

public class WebSecurity {

    public boolean checkPermission(String permission) {

        boolean hasPermission = true;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
                    .getRequest();
            HttpSession session = request.getSession();

            @SuppressWarnings("unchecked")
            List<String> functionList = (List<String>) session.getAttribute("FUNCTIONS");

            if (!functionList.contains(permission.toString())) {
                hasPermission = false;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("WebSecurity URL Permission " + permission + "hasPermission :"+hasPermission);
        return hasPermission;
    }
}

注意:如果用户已登录,isAuthenticate()将对所有URL进行身份验证。因此,请在此之前使用 access =“@ webSecurity.checkPermission('chkValue')”

<intercept-url access="isAnonymous()" pattern="/login"/>            
<intercept-url access="@webSecurity.checkPermission('S000017')" pattern="/addRequest"/>
<intercept-url access="isAuthenticated()" pattern="/**"/>