通用控制器中hasPermission的参数

时间:2014-06-12 00:13:37

标签: java spring spring-security spring-el

我正在尝试实现一个通用控制器类,其中每个方法都有类似于此的结构:

@RequestMapping(value="cadastra")
@PreAuthorize("hasPermission(#user, 'cadastra_#this.class.name')")
public ModelAndView cadastra() throws InstantiationException, IllegalAccessException {
    return new ModelAndView("privado/"+this.entity.getClass().getName()+"/cadastra", "command", this.entity.getClass().newInstance());
}

我在注释PreAuthorize时遇到问题。权限的名称有这个结构:_。现在,当我尝试访问该方法映射的视图时,我收到403错误。我还尝试了其他变体,如:

@PreAuthorize("hasPermission(#user, 'cadastra_'+#this.class.name)")

@PreAuthorize("hasPermission(#user, 'cadastra_#this.getClass().getName()')")

但结果相同。谁知道正确的方法来实现这个目标?

更新

我尝试在由此标签PreAuthorize:

保护的控制器的方法中调用此函数
private void expressionParser() {
    System.out.println("expressionHandler()");
    ExpressionParser parser = new SpelExpressionParser();
    Expression expression = parser.parseExpression("'cadastra_'+#this.class.name");
    String message = (String) expression.getValue();
    System.out.println("Message is " + message);
}

当我运行应用程序并打开视图时,应该通过控制器中的方法进行映射,如下所示:

@RequestMapping(value="cadastra")
@PreAuthorize("hasPermission(#user, 'cadastra_'+#this.class.name)")
public ModelAndView cadastra() throws InstantiationException, IllegalAccessException {
    this.expressionParser();
    return new ModelAndView("privado/"+this.entityClass.getName()+"/cadastra", "command", this.entityClass.newInstance());
}

控制台上未显示任何消息。所以,我认为我的应用程序不知道从我的通用控制器调用方法。我对吗?如果是这样,我如何解决这个问题?

我的派生控制器遵循以下结构:

@Controller
@RequestMapping(value="usuario")
public class UsuarioController extends controller<Usuario> {

    public UsuarioController() {
        super(Usuario.class);
    }

}

2 个答案:

答案 0 :(得分:7)

因此,您在SpEL表达式中以[methodName] _ [classFullName]的形式动态构造权限名称时遇到困难。

请参阅SpEL文档中有关#this变量

的内容
  

变量#this始终定义并引用当前评估对象   (解决了不合格的参考资料)。

根据文档并在代码中挖掘一下,#this表示的实际对象应该是org.springframework.security.access.expression.method.MethodSecurityExpressionRoot类的实例。该类包含几个有用的方法,还包括getThis()方法,该方法返回目标对象,在该目标对象上调用安全方法(使用@PreAuthorize注释的方法)。

有了这些知识,构建你需要的表达式应该不是什么大问题。如果名为&#34; cadastra&#34;的方法,则应如下所示。

@PreAuthorize("hasPermission(#user, 'cadastra_'+#this.this.class.name)")

希望它对于从基类继承的安全方法也能正常工作。

答案 1 :(得分:2)

所以,我用这种方法解决了这个问题:

1)向我的通用控制器添加一个新方法,在那里我返回类的名称:

public String getName() {
    String expressao = entityClass.getName();
    String nome_classe = new String();
    StringTokenizer st = new StringTokenizer(expressao, ".");
    while (st.hasMoreTokens()) {
        nome_classe = st.nextToken();
    }
    return nome_classe;
}

2)在注释中,我使用此方法返回的值并将结果与​​常量字符串连接(使用本主题中用户@pgjecek描述的符号):

@PreAuthorize("hasPermission(#user, 'cadastra_'+#this.this.name)")

现在它完美运作。