guice - Is an unbound SecurityManager really an invalid application configuration in Shiro? -


i'm adding apache shiro application , i'm wondering if following error message accurate:

org.apache.shiro.unavailablesecuritymanagerexception: no securitymanager accessible calling code, either bound org.apache.shiro.util.threadcontext or vm static singleton. invalid application configuration.

i've looked through source code bit , impression long i'm not using securityutils , i'm willing pass securitymanager components need it, don't need assign securitymanager static singleton used securityutils.

the specific thing want avoid having shiro put threadlocal or having shiro use threadcontext support class. i'm using apache thrift , don't want commit myself one-thread-per-request network design. requirements shiro pretty minimal, i'll show i'm doing below.

i'm using guice in application, i'm not using shiro-guice because shiro aop stuff depends on having subject associated threadcontext. instead, start extremely simple guice module.

public class shiroinimodule extends abstractmodule {     @override     protected void configure() {}      @provides     @singleton     public securitymanager providesecuritymanager() {         return new defaultsecuritymanager(new inirealm("classpath:shiro.ini"));     } } 

that's not production quality realm / security manager setup, it's enough me test with. next, create own manager classes limited scope used components of application. have 2 of these; thriftauthenticationmanager , thriftauthorizationmanager. here former:

@singleton public class thriftauthenticationmanager {     private final logger log = loggerfactory.getlogger(thriftauthenticationmanager.class);      private final securitymanager securitymanager;      @inject     public thriftauthenticationmanager(securitymanager securitymanager) {         this.securitymanager = securitymanager;     }      public string authenticate(string username, string password) throws texception {         try {             subject currentuser = new subject.builder(securitymanager).buildsubject();              if (!currentuser.isauthenticated()) {                 currentuser.login(new usernamepasswordtoken(username, password));             }              string authtoken = currentuser.getsession().getid().tostring();             preconditions.checkstate(!strings.isnullorempty(authtoken));             return authtoken;         }         catch (authenticationexception e) {             throw exceptions.security(securityexceptions.authentication_exception);         }         catch(throwable t) {             log.error("unexpected error during authentication.", t);             throw new texception("unexpected error during authentication.", t);         }      } } 

and latter:

@singleton public class thriftauthorizationmanager {     private final logger log = loggerfactory.getlogger(thriftauthorizationmanager.class);      private final securitymanager securitymanager;      @inject     public thriftauthorizationmanager(securitymanager securitymanager) {         this.securitymanager = securitymanager;     }      public void checkpermissions(final string authtoken, final string permissions)             throws texception {         withthriftexceptions(new callable<void>() {             @override             public void call() throws exception {                 securitymanager.checkpermission(getprincipals(authtoken), permissions);                 return null;             }         });     }      public void checkpermission(final string authtoken, final permission permission)             throws texception {         withthriftexceptions(new callable<void>() {             @override             public void call() throws exception {                 securitymanager.checkpermission(getprincipals(authtoken), permission);                 return null;             }         });     }      private subject getsubject(string authtoken) {         return new subject.builder(securitymanager).sessionid(authtoken).buildsubject();     }      private principalcollection getprincipals(string authtoken) {         return getsubject(authtoken).getprincipals();     }      private void withthriftexceptions(callable<void> callable) throws texception {         try {             callable.call();         }         catch(sessionexception e) {             throw exceptions.security(securityexceptions.session_exception);         }         catch(unauthenticatedexception e) {             throw exceptions.security(securityexceptions.unauthenticated_exception);         }         catch(authorizationexception e) {             throw exceptions.security(securityexceptions.authorization_exception);         }         catch(shiroexception e) {             throw exceptions.security(securityexceptions.security_exception);         }         catch(throwable t) {             log.error("an unexpected error occurred during authorization.", t);             throw new texception("unexpected error during authorization.", t);         }     } } 

my thrift services use above 2 classes authentication , authorization. example:

@singleton public class echoserviceimpl implements echoservice.iface {     private final logger log = loggerfactory.getlogger(echoserviceimpl.class);      private final thriftauthorizationmanager authorizor;      @inject     public echoserviceimpl(thriftauthorizationmanager authorizor) {         this.authorizor = authorizor;     }      @override     public echo echo(string authtoken, echo echo) throws texception {         authorizor.checkpermissions(authtoken, "echo");         return echo;     } } 

so, guess have few questsions.

  1. is error quoted error or overzealous log message?

  2. do need worry shiro relying on in threadcontext if never use shiroutils?

  3. is there harm in using securityutils#setsecuritymanager if can't guarantee one-thread-per-request environment?

  4. i haven't tried using shiro's advanced permissions (org.apache.shiro.authz.permission) yet. rely on in threadcontext or weird should sooner later?

  5. have done else cause me problems or improve anything?

  1. the error quoted error if want call securityutils.getsecuritymanager(). you're more welcome pass around manually or inject dependency outside of securityutils usage.

  2. securityutils convenience using shiro if want use it. few things within shiro call explicitly: of shiro's aspectj integration calls it, of shiro's web support calls (servlet filters, jsp , jsf taglibs). however, in these cases used within shiro, (i think) called template method, allowing override method acquire subject somewhere else if desired.

  3. no harm in calling securityutils.setsecuritymanager long you're comfortable single securitymanager instance entire jvm. if have more 1 shiro app uses method in same jvm, cause problems. however, because static memory calls , global state evil, if can find way of referencing securitymanager, better (e.g. dependency injection)

  4. shiro permissions not rely on threadcontext related. permission checks delegated 1 or more realms, , have final permitted or not. realms in turn use authorization cache ensure permission lookups stay nice , responsive. not thread state - it's (non static) application singleton state.

  5. your code looks pretty good. 1 recommendation thriftauthorizationmanager authorization checks delegate subject directly (the subject in turn delegates securitymanager). think tad faster current approach , better self-documenting imo:

    return getsubject(authtoken).checkpermission(permission); 

thanks sharing questions. nice see non-web usages of framework, since designed workloads.


Comments

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

android - send complex objects as post php java -

charts - What graph/dashboard product is facebook using in Dashboard: PUE & WUE -