Picketlink:如何获取注释参数和使用@Secures时装饰的函数的名称?

时间:2015-02-12 13:20:03

标签: java reflection annotations picketlink

我正在尝试定义和使用名为BasicRolesAllowed的自定义安全绑定类型,如Picketlink快速入门here中所示。

我的类型与快速入门中的类型之间唯一不同的是,我的注释必须接受一个字符串数组(我们希望使用不仅仅使用一个但可能使用角色的组合来保护方法),因此我的注释被定义为:

public @interface BasicRolesAllowed {
    String[] value() default {};
}

在快速入门之后,我试图定义此装饰器如何进行身份验证:

@Secures
@BasicRolesAllowed
public boolean doAdminCheck(Identity identity, IdentityManager identityManager, RelationshipManager relationshipManager) throws Exception {
    /*
     Sample usage of @BasicRolesAllowed is like:
      @BasicRolesAllowed(value = RoleConstants.CREATE_USER)
      TODO: need to get these from the @BasicRolesAllowed annotation instance/usage
      */

    String[] requiredRoles = {};// get these from annotation
    boolean isAuthorized = true;

    for (String role : requiredRoles)
        isAuthorized = isAuthorized && hasRole(relationshipManager, identity.getAccount(), getRole(identityManager, role));

    return isAuthorized;
}

正如在片段中可以看到的,技巧部分是:

        String[] requiredRoles = {};// get these from annotation

如何获取传递给装饰方法上的注释的字符串常量,以便我可以在查找角色时使用它们?

一些提示:

对于类似的问题here有一个答案,但问题是在那个解决方案中;我需要知道装饰函数或类的名称 - 在我的情况下是不可能的,因为装饰器几乎可以在任何地方使用,我不知道如何通过Picketlink快速入门中显示的方法获得这些。

此外,该解决方案仅显示如何获取传递给期望只有1个字符串的注释的值 - 也许我可以尝试使用values(),但上述限制仍然挡在我的路上。

提前感谢任何可以提供帮助的人。

1 个答案:

答案 0 :(得分:0)

感谢@pedroigor在#picketlink(freenode),解决方案可以从picketlink快速启动here中的这种用例的示例中收集。在该文件中,定义了一个方法getAnnotation(),该方法具有签名:

private <T extends Annotation> T getAnnotation(InvocationContext invocationContext, Class<T> annotationType)

所以,使用这个方法,我能够内省并获取传递给我的注释的值,这可以在我的角色检查方法的新实现中看到:

@Secures
@BasicRolesAllowed
public boolean hasBasicRolesCheck(InvocationContext invocationContext, Identity identity, IdentityManager identityManager, RelationshipManager relationshipManager) throws Exception {
    BasicRolesAllowed basicRolesAllowed = getAnnotation(invocationContext,BasicRolesAllowed.class);

    String[] requiredRoles = basicRolesAllowed.value();// get these from annotation
    boolean isAuthorized = true;

    for (String role : requiredRoles)
        isAuthorized = isAuthorized && hasRole(relationshipManager, identity.getAccount(), getRole(identityManager, role));

    return isAuthorized;
}

基本修改是:

  1. 我必须通过将此参数作为参数添加到我的方法定义中来传递调用上下文InvocationContext invocationContext的实例(CDI魔术会处理我听到的所有其他内容)。
  2. 然后我通过调用:

    获取注释实例
    BasicRolesAllowed basicRolesAllowed = getAnnotation(invocationContext,BasicRolesAllowed.class);
    
  3. 然后获取传递给注释的值/参数:

    String[] requiredRoles = basicRolesAllowed.value();// get these from annotation
    
  4. 这解决了我的问题: - )