You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@deltaspike.apache.org by "The Alchemist (JIRA)" <ji...@apache.org> on 2015/10/29 01:26:27 UTC

[jira] [Created] (DELTASPIKE-1014) SecuredAnnotationAuthorizer overwrites method-level annotation metadata with class-level annotation metadata

The Alchemist created DELTASPIKE-1014:
-----------------------------------------

             Summary: SecuredAnnotationAuthorizer overwrites method-level annotation metadata with class-level annotation metadata
                 Key: DELTASPIKE-1014
                 URL: https://issues.apache.org/jira/browse/DELTASPIKE-1014
             Project: DeltaSpike
          Issue Type: Bug
          Components: Security-Module
    Affects Versions: 1.5.1
         Environment: Weld 2.2.15.Final
            Reporter: The Alchemist


h2. Short Overview of What I'm trying to Do

I'm trying to make a CDI-based equivalent of {{javax.annotation.security.RolesAllowed}} that uses my custom {{ROLE}} enum.

{code:java}
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
@Inherited
@Stereotype
@Secured(MyRoleAccessDecisionVoter.class)
public @interface MyRolesAllowed {

    ROLE[] value();

}

@RequestScoped
public class MyRoleAccessDecisionVoter extends AbstractAccessDecisionVoter {
    @Inject
    private Principal principal;

    @Override
    protected void checkPermission(AccessDecisionVoterContext voterContext, Set<SecurityViolation> violations) {
        // get the roles from the annotation
        ROLE[] rolesAllowed = voterContext.getMetaDataFor(MyRolesAllowed.class.getName(), MyRolesAllowed.class).value();
        // BUG ABOVE!  it'll have class-level annotation instead of the method-level annotation
    }
}
        
@MyRolesAllowed({ADMIN, ROOT, USER})
@Stateless
public class TestBean {
    @MyRolesAllowed({ADMIN, ROOT})
    public List<String> getWhatever() {
        return ImmutableList.of();
    }
}
{code}

h2. My Thoughts

It looks like {{org.apache.deltaspike.security.impl.authorization.SecuredAnnotationAuthorizer}} is where the bug is.

It parses both method- and class-level annotations in {{extractMetadata()}}, in that order (method first, then class).

Then that data gets passed to {{DefaultAccessDecisionVoterContext.addMetaData()}}, which puts it in a {{HashMap}}.

Because the order is method-first, that entry in the map gets overwritten by the class-level info.

h2. Possible Fixes?

* Flip the order in {{extractMetaData()}}: first get the class-level, then the method-level, so the method level will overwrite the class-level 
* {{getMetaData()}} should return a {{List}} instead, and down the road, perhaps the super-class metadata can be put there too

I guess the issue is whether the annotations should be MERGED or OVERWRITTEN.  I'm guessing you guys had similar discussions for {{org.apache.deltaspike.core.api.config.view.metadata.Aggregated}}.

I'm thinking that it should OVERWRITE by default.

h2. Workaround?

Unknown. :(  Anyone have any suggestions? Is there a way to use a custom {{DefaultAccessDecisionVoterContext}} or {{SecuredAnnotationAuthorizer}}?



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)