You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by Ken Han <ha...@gmail.com> on 2018/04/13 13:31:36 UTC

Shiro Guice - Requires annotations are ignored/unprocessed

I'm experimenting with Shiro + Guice with the goal of using them to implement
an authorization service in a jsf web application. But I'm having trouble
with getting the @RequiresRoles and @RequiresPermissions to actually work.
It looks like they are being ignored.

My shiro module looks like this:


public class MyShiroModule extends ShiroModule {

private final String DUKE_ROLE = "duke";

private final DomainPermission DUKE_PERMISSION = new
DomainPermission("duking");

@Override
protected void configureShiro() {
    MySimpleAccountRealm simpleAccountRealm = new
MySimpleAccountRealm("Feudal realm");

    Set<Permission> duke_permissions = new HashSet<>();
    duke_permissions.add(DUKE_PERMISSION);

    SimpleRole duke = new SimpleRole(DUKE_ROLE, duke_permissions);

    simpleAccountRealm.addAccount("kenzo", "atreides", duke);

    bindRealm().toInstance(simpleAccountRealm);
}
}



As you can see I've created my own Realm and added a user with a sing role
and permission. I've created an extension of the SimpleAccountRealm because
I wanted to add roles with permissions to an account.

MySimpleAccountRealm looks like this:


public class MySimpleAccountRealm extends SimpleAccountRealm {

public MySimpleAccountRealm(String name) {
    super(name);
}

    public void addAccount(String username, String password, SimpleRole...
roles) {
    //Get all the role names from the roles array
    Set<String> roleNames =
Arrays.stream(roles).map(SimpleRole::getName).collect(Collectors.toSet());

    //Get every permission from the roles
    Set<Permission> permissions = new HashSet<>();
    Arrays.stream(roles).forEach(r ->
permissions.addAll(r.getPermissions()));

    SimpleAccount account = new SimpleAccount(username, password, getName(),
roleNames, permissions);
    add(account);
}
}



I have a simple Main class:


public class Main {
public static void main(String[] args) {
    GuiceTest test = new GuiceTest();
    test.gogo();
}
}



My test class looks like:


public class GuiceTest {
private Injector injector;
private SecurityManager securityManager;

public GuiceTest() {
    injector = Guice.createInjector(new MyShiroModule(), new
ShiroAopModule());
    securityManager = injector.getInstance(SecurityManager.class);
    SecurityUtils.setSecurityManager(securityManager);
}

public void gogo() {
    Subject currentUser = SecurityUtils.getSubject();
    loginUser(currentUser);

    testValidWithoutAnnotation(currentUser);
    testInvalidWithoutAnnotation(currentUser);
    testValidRoleAnnotation();
    testInvalidRoleAnnotation();

    currentUser.logout();
}


private void loginUser(Subject currentUser) {
    if (!currentUser.isAuthenticated()) {
        UsernamePasswordToken token = new UsernamePasswordToken("kenzo",
"atreides");
        token.setRememberMe(true);
        try {
            currentUser.login(token);

            //say who they are:
            //print their identifying principal (in this case, a username):
            System.out.println("User [" + currentUser.getPrincipal() + "]
logged in successfully.");
        } catch (UnknownAccountException uae) {
            System.out.println("There is no user with username of " +
token.getPrincipal());
        } catch (IncorrectCredentialsException ice) {
            System.out.println("Password for account " +
token.getPrincipal() + " was incorrect!");
        } catch (LockedAccountException lae) {
            System.out.println("The account for username " +
token.getPrincipal() + " is locked.  " +
                    "Please contact your administrator to unlock it.");
        }
        // ... catch more exceptions here (maybe custom ones specific to
your application?
        catch (AuthenticationException ae) {
            //unexpected condition?  error?
        }
    }
}


    @RequiresRoles("dontHaveThisRoles")
    public void testInvalidRoleAnnotation() {
        System.out.println("Testing (with annotation) that the user has the
role 'dontHaveThisRoles'. User doesn't have this, so it should cause an
AuthenticationException.");
    }

    @RequiresRoles("duke")
    public void testValidRoleAnnotation() {
        System.out.println("Testing (with annotation) that the user has the
role 'duke'. User has this role, so this should be printed.");
    }

    private void testValidWithoutAnnotation(Subject currentUser) {
        if (currentUser.hasRole("duke")) {
            System.out.println("Testing (without annotation) that the user
has the role 'duke'. User has this role.");

        } else {
            System.out.println("Pleb");
        }
    }

    private void testInvalidWithoutAnnotation(Subject currentUser) {
        if (!currentUser.hasRole("nope")) {
            System.out.println("Testing (without annotation) that the user
has the role 'nope'. User doesn't have this role.");
        }
    }

}





When running the application I get the following output:

User [kenzo] logged in successfully.
Testing (without annotation) that the user has the role 'duke'. User has
this role.
Testing (without annotation) that the user has the role 'nope'. User doesn't
have this role.
Testing (with annotation) that the user has the role 'duke'. User has this
role, so this should be printed.
Testing (with annotation) that the user has the role 'dontHaveThisRoles'.
User doesn't have this, so it should cause an AuthenticationException.




The problem lies in the fifth line. Since the logged in user doesn't have
the 'dontHaveThisRoles' role, I expected an AuthenticationException. But
this doesn't happen. I've been debugging the assertAuthorized method in the
RoleAnnotationHandler class to see what's happening. But it looks like I
don't even enter the assertAuthorized method.




Note: My dependencies:

    <dependencies>
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-guice</artifactId>
        <version>1.4.0</version>
    </dependency>


    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.1</version>
    </dependency>
    </dependencies>


Since I'm creating my own realm, I don't have a shiro.ini file.




--
Sent from: http://shiro-user.582556.n2.nabble.com/

Re: Shiro Guice - Requires annotations are ignored/unprocessed

Posted by Brian Demers <br...@gmail.com>.
I'm guessing your GuiceTest isn't getting picked up by any AOP processing.
It is likely just still a POJO at that time when you call your methods.
IIRC, if you move those annotated methods to a guice component they will
start to work.

On Fri, Apr 13, 2018 at 9:31 AM, Ken Han <ha...@gmail.com> wrote:

> I'm experimenting with Shiro + Guice with the goal of using them to
> implement
> an authorization service in a jsf web application. But I'm having trouble
> with getting the @RequiresRoles and @RequiresPermissions to actually work.
> It looks like they are being ignored.
>
> My shiro module looks like this:
>
>
> public class MyShiroModule extends ShiroModule {
>
> private final String DUKE_ROLE = "duke";
>
> private final DomainPermission DUKE_PERMISSION = new
> DomainPermission("duking");
>
> @Override
> protected void configureShiro() {
>     MySimpleAccountRealm simpleAccountRealm = new
> MySimpleAccountRealm("Feudal realm");
>
>     Set<Permission> duke_permissions = new HashSet<>();
>     duke_permissions.add(DUKE_PERMISSION);
>
>     SimpleRole duke = new SimpleRole(DUKE_ROLE, duke_permissions);
>
>     simpleAccountRealm.addAccount("kenzo", "atreides", duke);
>
>     bindRealm().toInstance(simpleAccountRealm);
> }
> }
>
>
>
> As you can see I've created my own Realm and added a user with a sing role
> and permission. I've created an extension of the SimpleAccountRealm because
> I wanted to add roles with permissions to an account.
>
> MySimpleAccountRealm looks like this:
>
>
> public class MySimpleAccountRealm extends SimpleAccountRealm {
>
> public MySimpleAccountRealm(String name) {
>     super(name);
> }
>
>     public void addAccount(String username, String password, SimpleRole...
> roles) {
>     //Get all the role names from the roles array
>     Set<String> roleNames =
> Arrays.stream(roles).map(SimpleRole::getName).collect(Collectors.toSet());
>
>     //Get every permission from the roles
>     Set<Permission> permissions = new HashSet<>();
>     Arrays.stream(roles).forEach(r ->
> permissions.addAll(r.getPermissions()));
>
>     SimpleAccount account = new SimpleAccount(username, password,
> getName(),
> roleNames, permissions);
>     add(account);
> }
> }
>
>
>
> I have a simple Main class:
>
>
> public class Main {
> public static void main(String[] args) {
>     GuiceTest test = new GuiceTest();
>     test.gogo();
> }
> }
>
>
>
> My test class looks like:
>
>
> public class GuiceTest {
> private Injector injector;
> private SecurityManager securityManager;
>
> public GuiceTest() {
>     injector = Guice.createInjector(new MyShiroModule(), new
> ShiroAopModule());
>     securityManager = injector.getInstance(SecurityManager.class);
>     SecurityUtils.setSecurityManager(securityManager);
> }
>
> public void gogo() {
>     Subject currentUser = SecurityUtils.getSubject();
>     loginUser(currentUser);
>
>     testValidWithoutAnnotation(currentUser);
>     testInvalidWithoutAnnotation(currentUser);
>     testValidRoleAnnotation();
>     testInvalidRoleAnnotation();
>
>     currentUser.logout();
> }
>
>
> private void loginUser(Subject currentUser) {
>     if (!currentUser.isAuthenticated()) {
>         UsernamePasswordToken token = new UsernamePasswordToken("kenzo",
> "atreides");
>         token.setRememberMe(true);
>         try {
>             currentUser.login(token);
>
>             //say who they are:
>             //print their identifying principal (in this case, a username):
>             System.out.println("User [" + currentUser.getPrincipal() + "]
> logged in successfully.");
>         } catch (UnknownAccountException uae) {
>             System.out.println("There is no user with username of " +
> token.getPrincipal());
>         } catch (IncorrectCredentialsException ice) {
>             System.out.println("Password for account " +
> token.getPrincipal() + " was incorrect!");
>         } catch (LockedAccountException lae) {
>             System.out.println("The account for username " +
> token.getPrincipal() + " is locked.  " +
>                     "Please contact your administrator to unlock it.");
>         }
>         // ... catch more exceptions here (maybe custom ones specific to
> your application?
>         catch (AuthenticationException ae) {
>             //unexpected condition?  error?
>         }
>     }
> }
>
>
>     @RequiresRoles("dontHaveThisRoles")
>     public void testInvalidRoleAnnotation() {
>         System.out.println("Testing (with annotation) that the user has the
> role 'dontHaveThisRoles'. User doesn't have this, so it should cause an
> AuthenticationException.");
>     }
>
>     @RequiresRoles("duke")
>     public void testValidRoleAnnotation() {
>         System.out.println("Testing (with annotation) that the user has the
> role 'duke'. User has this role, so this should be printed.");
>     }
>
>     private void testValidWithoutAnnotation(Subject currentUser) {
>         if (currentUser.hasRole("duke")) {
>             System.out.println("Testing (without annotation) that the user
> has the role 'duke'. User has this role.");
>
>         } else {
>             System.out.println("Pleb");
>         }
>     }
>
>     private void testInvalidWithoutAnnotation(Subject currentUser) {
>         if (!currentUser.hasRole("nope")) {
>             System.out.println("Testing (without annotation) that the user
> has the role 'nope'. User doesn't have this role.");
>         }
>     }
>
> }
>
>
>
>
>
> When running the application I get the following output:
>
> User [kenzo] logged in successfully.
> Testing (without annotation) that the user has the role 'duke'. User has
> this role.
> Testing (without annotation) that the user has the role 'nope'. User
> doesn't
> have this role.
> Testing (with annotation) that the user has the role 'duke'. User has this
> role, so this should be printed.
> Testing (with annotation) that the user has the role 'dontHaveThisRoles'.
> User doesn't have this, so it should cause an AuthenticationException.
>
>
>
>
> The problem lies in the fifth line. Since the logged in user doesn't have
> the 'dontHaveThisRoles' role, I expected an AuthenticationException. But
> this doesn't happen. I've been debugging the assertAuthorized method in the
> RoleAnnotationHandler class to see what's happening. But it looks like I
> don't even enter the assertAuthorized method.
>
>
>
>
> Note: My dependencies:
>
>     <dependencies>
>     <dependency>
>         <groupId>org.apache.shiro</groupId>
>         <artifactId>shiro-guice</artifactId>
>         <version>1.4.0</version>
>     </dependency>
>
>
>     <dependency>
>         <groupId>commons-logging</groupId>
>         <artifactId>commons-logging</artifactId>
>         <version>1.1.1</version>
>     </dependency>
>     </dependencies>
>
>
> Since I'm creating my own realm, I don't have a shiro.ini file.
>
>
>
>
> --
> Sent from: http://shiro-user.582556.n2.nabble.com/
>