You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@shiro.apache.org by ApacheNinja <dp...@gmail.com> on 2013/05/15 03:46:45 UTC

Too many threads created when calling isPermitted()

We are noticing in our implementation of Shiro that every time a user logs in
a new thread is created.  We also notice that when permissions are being
checked via the isPermitted() method (on the DelegatingSubject object) a new
thread is also created.   Our code has not been put in production yet where
there are a lot of users, however, we suspect the server will crash if we
do.  Has anybody ran into this issue before?  How do Shiro threads work when
calling the isPermitted() method?  Thank you in advance.



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725.html
Sent from the Shiro User mailing list archive at Nabble.com.

RE: Too many threads created when calling isPermitted()

Posted by Ken in Nashua <kc...@live.com>.
Yea I am scratching my head myself... 
all of a sudden this framework appears out of the blue
many questions to be answered
but I believe its just the open source bilderbergers
and you may never get the answers maybe for years
but its on the table... deal with it
 		 	   		  

Re: Too many threads created when calling isPermitted()

Posted by ApacheNinja <dp...@gmail.com>.
Hello Les,

Thank you for the information.  It turns out the reason why the correct
realm was not being used was because I was configuring a single realm each
time as opposed to a collection of realms.  The PortalRealm was being
overwritten with the BaselinePortalRealm.  We were configuring single realms
when we were using more that one security manager.  That being said, I have
to configure a collection of realms that contain the 2 realms that I want to
utilize.  

I did in fact take a look a the source code for the ModularRealmAuthorizer
shortly before you posted.  The functionality we need now is to ALWAYS check
both realms (as opposed to having it short circuit if one realm is true via
the documentation).  I have created a custom class that extends
ModularRealmAuthorizer.  I see that there is not a strategy that I can pass
it similar to the authentication "AllSuccessfulStrategy".  Would my only
option to be to go into the code and modify it so that it checks both
realms?  I have modified the two main methods below, however, it seems that
I may need to modify some other methods.  

The easier way would be to inspect the Principals and have the realm return
null if it should not participate in the authorization.  That way we don't
have to call both realms, but just the correct one.  However, I don't know
if I have the information I need in the Principals object.  I will check.

	
  /**
   * Returns <code>true</code> if ALL of the configured realms'
   * {@link #isPermitted(org.apache.shiro.subject.PrincipalCollection,
String)} returns <code>true</code>,
   * <code>false</code> otherwise.
  */
	@Override
  public boolean isPermitted(PrincipalCollection principals, String
permission) {
			assertRealmsConfigured();
      for (Realm realm : getRealms()) {
          if (!(realm instanceof Authorizer)) continue;
          if (!((Authorizer) realm).isPermitted(principals, permission)) {
                 return false;
           }
       }
       return true;
   }
 
	
	/**
	 * Returns <code>true</code> if ALL of the configured realms'
	 * {@link #isPermitted(org.apache.shiro.subject.PrincipalCollection,
Permission)} call returns <code>true</code>,
	 * <code>false</code> otherwise.
	*/
	@Override
	public boolean isPermitted(PrincipalCollection principals, Permission
permission) {
			assertRealmsConfigured();
			for (Realm realm : getRealms()) {
				if (!(realm instanceof Authorizer)) continue;
				if (!((Authorizer) realm).isPermitted(principals, permission)) {
						return false;
	       }
	     }
	    return true;
	}


Les Hazlewood-2 wrote
> P.S. The SecurityManager defaults to using an instance of
> ModularRealmAuthorizer [1] to coordinate how Realms are consulted
> during an authorization check.
> 
> You can look at that and see how it works, or you could always just
> implement a custom Authorizer that coordinates with your Realms
> however you see fit.
> 
> [1]
> https://github.com/apache/shiro/blob/trunk/core/src/main/java/org/apache/shiro/authz/ModularRealmAuthorizer.java
> 
> --
> Les Hazlewood | @lhazlewood
> CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282
> 
> 
> On Thu, May 16, 2013 at 9:43 AM, Les Hazlewood &lt;

> lhazlewood@

> &gt; wrote:
>> It is expected that all available realms are configured on the
>> SecurityManager at application startup.  The SecurityManager will
>> coordinate the Realms (often through an Authenticator or Authorizer)
>> instance during authentication and authorization.
>>
>> A Realm can choose to participate in an authentication attempt by
>> implementing the supports(AuthenticationToken) method.
>>
>> A Realm can choose to participate in an authorization check by
>> returning null or false (depending on the method being called).  Also,
>> for AuthorizingRealm implementations (as most Realms are), you can, in
>> the doGetAuthorizationInfo method implementation, inspect the
>> PrincipalCollection argument.  If your realm recognizes the
>> PrincipalCollection, it can return an AuthorizationInfo instance.  If
>> it doesn't recognize it, it can return null.
>>
>> The sequence for Realm authorization is covered here:
>> http://shiro.apache.org/authorization.html#Authorization-AuthorizationSequence
>>
>> Also, I highly recommend seeing the AuthorizingRealm source code so
>> you can get a feel for how it works and what features there are that
>> you can leverage (e.g. authorization caching):
>> https://github.com/apache/shiro/blob/trunk/core/src/main/java/org/apache/shiro/realm/AuthorizingRealm.java
>>
>> HTH,
>> --
>> Les Hazlewood | @lhazlewood
>> CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282
>>
>>
>> On Wed, May 15, 2013 at 3:51 PM, ApacheNinja &lt;

> dpryce7@

> &gt; wrote:
>>> Hello,
>>>
>>> After further investigation I see the problem but I do not know why it
>>> is
>>> doing this.   I see the DefaultSecurityManager has an Authorizer object
>>> that
>>> has a list of realms.  We have 2 types of realm objects: A PortalRealm
>>> and a
>>> PortalBaselineRealm.   When the isPermitted() is called for a user, it
>>> should use the PortalRealm object.  However, running the debugger I see
>>> that
>>> there is 1 object in the realms list and it is a PortalBaseRealm.  It
>>> should
>>> be the PortalRealm.  This only started happening when changed the code
>>> to
>>> use one Security Manager.  This does not happen when I create a new
>>> Security
>>> Manager object each time I authenticate (the old way).  We are setting
>>> the
>>> realm on the Security Manager object via
>>> securityManager.setRealm(realm).
>>> Thank you for your help in advance.
>>>
>>>
>>>
>>> --
>>> View this message in context:
>>> http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725p7578741.html
>>> Sent from the Shiro User mailing list archive at Nabble.com.





--
View this message in context: http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725p7578747.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Too many threads created when calling isPermitted()

Posted by Les Hazlewood <lh...@apache.org>.
P.S. The SecurityManager defaults to using an instance of
ModularRealmAuthorizer [1] to coordinate how Realms are consulted
during an authorization check.

You can look at that and see how it works, or you could always just
implement a custom Authorizer that coordinates with your Realms
however you see fit.

[1] https://github.com/apache/shiro/blob/trunk/core/src/main/java/org/apache/shiro/authz/ModularRealmAuthorizer.java

--
Les Hazlewood | @lhazlewood
CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282


On Thu, May 16, 2013 at 9:43 AM, Les Hazlewood <lh...@apache.org> wrote:
> It is expected that all available realms are configured on the
> SecurityManager at application startup.  The SecurityManager will
> coordinate the Realms (often through an Authenticator or Authorizer)
> instance during authentication and authorization.
>
> A Realm can choose to participate in an authentication attempt by
> implementing the supports(AuthenticationToken) method.
>
> A Realm can choose to participate in an authorization check by
> returning null or false (depending on the method being called).  Also,
> for AuthorizingRealm implementations (as most Realms are), you can, in
> the doGetAuthorizationInfo method implementation, inspect the
> PrincipalCollection argument.  If your realm recognizes the
> PrincipalCollection, it can return an AuthorizationInfo instance.  If
> it doesn't recognize it, it can return null.
>
> The sequence for Realm authorization is covered here:
> http://shiro.apache.org/authorization.html#Authorization-AuthorizationSequence
>
> Also, I highly recommend seeing the AuthorizingRealm source code so
> you can get a feel for how it works and what features there are that
> you can leverage (e.g. authorization caching):
> https://github.com/apache/shiro/blob/trunk/core/src/main/java/org/apache/shiro/realm/AuthorizingRealm.java
>
> HTH,
> --
> Les Hazlewood | @lhazlewood
> CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282
>
>
> On Wed, May 15, 2013 at 3:51 PM, ApacheNinja <dp...@gmail.com> wrote:
>> Hello,
>>
>> After further investigation I see the problem but I do not know why it is
>> doing this.   I see the DefaultSecurityManager has an Authorizer object that
>> has a list of realms.  We have 2 types of realm objects: A PortalRealm and a
>> PortalBaselineRealm.   When the isPermitted() is called for a user, it
>> should use the PortalRealm object.  However, running the debugger I see that
>> there is 1 object in the realms list and it is a PortalBaseRealm.  It should
>> be the PortalRealm.  This only started happening when changed the code to
>> use one Security Manager.  This does not happen when I create a new Security
>> Manager object each time I authenticate (the old way).  We are setting the
>> realm on the Security Manager object via securityManager.setRealm(realm).
>> Thank you for your help in advance.
>>
>>
>>
>> --
>> View this message in context: http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725p7578741.html
>> Sent from the Shiro User mailing list archive at Nabble.com.

Re: Too many threads created when calling isPermitted()

Posted by Les Hazlewood <lh...@apache.org>.
It is expected that all available realms are configured on the
SecurityManager at application startup.  The SecurityManager will
coordinate the Realms (often through an Authenticator or Authorizer)
instance during authentication and authorization.

A Realm can choose to participate in an authentication attempt by
implementing the supports(AuthenticationToken) method.

A Realm can choose to participate in an authorization check by
returning null or false (depending on the method being called).  Also,
for AuthorizingRealm implementations (as most Realms are), you can, in
the doGetAuthorizationInfo method implementation, inspect the
PrincipalCollection argument.  If your realm recognizes the
PrincipalCollection, it can return an AuthorizationInfo instance.  If
it doesn't recognize it, it can return null.

The sequence for Realm authorization is covered here:
http://shiro.apache.org/authorization.html#Authorization-AuthorizationSequence

Also, I highly recommend seeing the AuthorizingRealm source code so
you can get a feel for how it works and what features there are that
you can leverage (e.g. authorization caching):
https://github.com/apache/shiro/blob/trunk/core/src/main/java/org/apache/shiro/realm/AuthorizingRealm.java

HTH,
--
Les Hazlewood | @lhazlewood
CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282


On Wed, May 15, 2013 at 3:51 PM, ApacheNinja <dp...@gmail.com> wrote:
> Hello,
>
> After further investigation I see the problem but I do not know why it is
> doing this.   I see the DefaultSecurityManager has an Authorizer object that
> has a list of realms.  We have 2 types of realm objects: A PortalRealm and a
> PortalBaselineRealm.   When the isPermitted() is called for a user, it
> should use the PortalRealm object.  However, running the debugger I see that
> there is 1 object in the realms list and it is a PortalBaseRealm.  It should
> be the PortalRealm.  This only started happening when changed the code to
> use one Security Manager.  This does not happen when I create a new Security
> Manager object each time I authenticate (the old way).  We are setting the
> realm on the Security Manager object via securityManager.setRealm(realm).
> Thank you for your help in advance.
>
>
>
> --
> View this message in context: http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725p7578741.html
> Sent from the Shiro User mailing list archive at Nabble.com.

Re: Too many threads created when calling isPermitted()

Posted by ApacheNinja <dp...@gmail.com>.
Hello,

After further investigation I see the problem but I do not know why it is
doing this.   I see the DefaultSecurityManager has an Authorizer object that
has a list of realms.  We have 2 types of realm objects: A PortalRealm and a
PortalBaselineRealm.   When the isPermitted() is called for a user, it
should use the PortalRealm object.  However, running the debugger I see that
there is 1 object in the realms list and it is a PortalBaseRealm.  It should
be the PortalRealm.  This only started happening when changed the code to
use one Security Manager.  This does not happen when I create a new Security
Manager object each time I authenticate (the old way).  We are setting the
realm on the Security Manager object via securityManager.setRealm(realm). 
Thank you for your help in advance.



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725p7578741.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Too many threads created when calling isPermitted()

Posted by ApacheNinja <dp...@gmail.com>.
Hello Lez,

Thank you for your reply.  I have taken your advice an done the following:

1.  I have placed the following code in a class that gets initialized when
the application starts up:

private static DefaultSecurityManager mSecurityManager = new
DefaultSecurityManager();
mSecurityManager.setAuthenticator(new MockAuthenticator());
SecurityUtils.setSecurityManager(mSecurityManager);

2.  My new setAuthorizerSubject() method is below.  (It only gets executed
when the user logs in, it does not get executed every time we call
isPermitted() on the subject object.):

protected void setAuthorizerSubject(UsersDVO user){
   DefaultSecurityManager securityManager = (DefaultSecurityManager)
SecurityUtils.getSecurityManager();
   securityManager.setRealm(realm);
   SecurityUtils.setSecurityManager(securityManager ); //This line is
probably not needed?
   Subject currentUser =  new
Subject.Builder(securityManager).buildSubject();
   if(!currentUser.isAuthenticated()){
       UsernamePasswordToken token = new
UsernamePasswordToken(user.getUserName(), "");
        try{
                currentUser.login(token);
         } catch (AuthenticationException ex){
                Log.exception(ex);
         }
    }
        this.subject = currentUser;
 }

Now I have a new problem.  It seems that I am seeing different behavior now
that I am only using one security manager.  My permissions are not being
retrieved correctly.  After further inspection, it appears that  my
doGetAuthorizationInfo() method in my AuthorizingRealm is not being called
when checking permissions.  This was being called when I created a new
security manager.  As you can see above I am setting the realm in the
security manager above via securityManager.setRealm(realm).  Any ideas?


Les Hazlewood-2 wrote
> P.S. Also, if you authenticate a Subject every time you use it (e.g.
> like in REST calls, where you may authenticate every REST request),
> you don't need sessions, since Subject state is re-created on every
> authentication.  You can turn off sessions entirely.
> 
> This is all covered in the documentation:
> http://shiro.apache.org/session-management.html#SessionManagement-SessionsandSubjectState
> 
> HTH,
> 
> --
> Les Hazlewood | @lhazlewood
> CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282
> 
> On Wed, May 15, 2013 at 9:38 AM, Les Hazlewood &lt;

> lhazlewood@

> &gt; wrote:
>> Shiro does not create threads for permission checks.  What you're
>> seeing is a side-effect of non-standard Shiro usage.
>>
>> It is expected that you (or a config mechanism like shiro.ini or
>> Spring or Guice, etc) create one and only one SecurityManager instance
>> for your entire application.  Additionally, DelegatingSubject is an
>> internal implementation class in Shiro - it shouldn't be used directly
>> by application code (it only might ever be used by non-Shiro
>> developers if they are writing framework-integration code for Shiro -
>> not for standard app use cases).  If you need to create ad-hoc Subject
>> instances, you should use the Subject.Builder to create ad-hoc Subject
>> instances, passing in the SecurityManager as a constructor argument.
>>
>> In any event, here is what you are seeing:
>>
>> 1.  Shiro's default SecurityManager implementation has an internal
>> SessionManager.
>> 2.  This SessionManager, if sessions are used, will create a session
>> validation thread (to ensure that orphaned sessions can be cleaned
>> properly).
>> 3.  If you authenticate a user, Shiro's default storage mechanism for
>> authenticate state is the session.  Because of #2, this will start a
>> session validation thread.
>>
>> So by #2 and #3, if you create a SecurityManager for every
>> authentication, therefore, you'll create a session validation thread
>> for each authentication! (Thanks to Tamás for the hint).  So again,
>> permission checks don't create threads at all - what you're seeing is
>> an unrelated issue due to creating a new SecurityManager every time.
>>
>> Here's what I'd do in your scenario:
>>
>> - Create one and only one SecurityManager.  Set it on
>> SecurityUtils.setSecurityManager if you have to to ensure it is
>> re-used (although this is not recommended - you would ideally use
>> something like dependency injection or a configuration mechanism of
>> your choice that manages application singletons without using static
>> memory).
>>
>> - Don't create DelegatingSubject instances.  Use the Subject.Builder
>> if you have to create ad-hoc Subject instances.
>>
>> For example, (very similar to Christian's example):
>>
>> Subject subject = new
>> Subject.Builder(SecurityUtils.getSecurityManager()).buildSubject();
>> subject.login(usernamePasswordToken);
>> if (subject.isPermitted(whatever)) {
>>     do something
>> }
>>
>> Because you built the subject manually (and didn't use
>> SecurityUtils.getSubject()), the built subject is _not_ bound to the
>> current thread, so other calls to SecurityUtils.getSubject() will not
>> return the same Subject.  If you manually create Subject instances in
>> Shiro, you are responsible for ensuring thread association if you wish
>> to use SecurityUtils.getSubject() in other parts of your code.
>>
>> HTH,
>>
>> --
>> Les Hazlewood | @lhazlewood
>> CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282
>>
>>
>> On Wed, May 15, 2013 at 7:47 AM, Tamás Cservenák &lt;

> tamas@

> &gt; wrote:
>>> Session validating thread....?
>>>
>>> but by looking at the code, um, very strange use of Shiro.. :)
>>>
>>>
>>> On Wed, May 15, 2013 at 4:14 PM, ApacheNinja &lt;

> dpryce7@

> &gt; wrote:
>>>>
>>>> Hello,
>>>>
>>>> Yes, we are using the latest release of Shiro.   We are primarily using
>>>> Shiro to check user permissions.  We are not using it to log in to our
>>>> application.  We are creating our Subject using the following method:
>>>>
>>>> protected void setAuthorizerSubject(UsersDVO user){
>>>>         DefaultSecurityManager securityManager = new
>>>> DefaultSecurityManager();
>>>>         securityManager.setRealm(realm);
>>>>         securityManager.setAuthenticator(new MockAuthenticator());
>>>>         SecurityUtils.setSecurityManager(securityManager );
>>>>         Subject currentUser = new DelegatingSubject(securityManager);
>>>>         if(!currentUser.isAuthenticated()){
>>>>             UsernamePasswordToken token = new
>>>> UsernamePasswordToken(user.getUserName(), "");
>>>>             try{
>>>>                 currentUser.login(token);
>>>>             } catch (AuthenticationException ex){
>>>>                 Log.exception(ex);
>>>>             }
>>>>         }
>>>>         this.subject = currentUser;
>>>>     }
>>>>
>>>> This is created once when the user logs in.  In our application it is
>>>> possible to log in as a general administrator first, then log in again
>>>> as
>>>> a
>>>> more specific user.  So this may be called twice.  We then use the
>>>> Subject
>>>> object to call the isPermitted() object, which checks to see if the
>>>> user
>>>> has
>>>> access to different portions of our application.  In our Realm object
>>>> we
>>>> have set setAuthorizationCachingEnabled(false) (I don't think this
>>>> makes a
>>>> difference but I thought I would include this information anyway).
>>>> Looking
>>>> at the stack trace when calling isPermitted(), I see that it goes
>>>> through
>>>> the Shiro API and then it then calls our implementation
>>>> doGetAuthorizationInfo() :
>>>>
>>>>     @Override
>>>>     protected AuthorizationInfo
>>>> doGetAuthorizationInfo(PrincipalCollection
>>>> principalCollection) {
>>>>         SimpleAuthorizationInfo info = null;
>>>>         if( user != null ) {
>>>>             info = new SimpleAuthorizationInfo();
>>>>             List
> <Role>
>  roles =
>>>> roleManager.getRolesForUser(user.getUserID());
>>>>             List
> <EPermission>
>  permissions =
>>>> permissionManager.getPermissionsForUser(user.getUserID());
>>>>             for(Role role : roles) {
>>>>                 info.addRole(role.getName());
>>>>             }
>>>>             for(EPermission permission : permissions){
>>>>                 info.addStringPermission(permission.getName());
>>>>             }
>>>>         }
>>>>
>>>>         return info;
>>>>     }
>>>>
>>>> Somewhere in there a new thread is being generated but I don't know
>>>> where.
>>>>
>>>>
>>>>
>>>> --
>>>> View this message in context:
>>>> http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725p7578734.html
>>>> Sent from the Shiro User mailing list archive at Nabble.com.
>>>
>>>





--
View this message in context: http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725p7578740.html
Sent from the Shiro User mailing list archive at Nabble.com.

Re: Too many threads created when calling isPermitted()

Posted by Les Hazlewood <lh...@apache.org>.
P.S. Also, if you authenticate a Subject every time you use it (e.g.
like in REST calls, where you may authenticate every REST request),
you don't need sessions, since Subject state is re-created on every
authentication.  You can turn off sessions entirely.

This is all covered in the documentation:
http://shiro.apache.org/session-management.html#SessionManagement-SessionsandSubjectState

HTH,

--
Les Hazlewood | @lhazlewood
CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282

On Wed, May 15, 2013 at 9:38 AM, Les Hazlewood <lh...@apache.org> wrote:
> Shiro does not create threads for permission checks.  What you're
> seeing is a side-effect of non-standard Shiro usage.
>
> It is expected that you (or a config mechanism like shiro.ini or
> Spring or Guice, etc) create one and only one SecurityManager instance
> for your entire application.  Additionally, DelegatingSubject is an
> internal implementation class in Shiro - it shouldn't be used directly
> by application code (it only might ever be used by non-Shiro
> developers if they are writing framework-integration code for Shiro -
> not for standard app use cases).  If you need to create ad-hoc Subject
> instances, you should use the Subject.Builder to create ad-hoc Subject
> instances, passing in the SecurityManager as a constructor argument.
>
> In any event, here is what you are seeing:
>
> 1.  Shiro's default SecurityManager implementation has an internal
> SessionManager.
> 2.  This SessionManager, if sessions are used, will create a session
> validation thread (to ensure that orphaned sessions can be cleaned
> properly).
> 3.  If you authenticate a user, Shiro's default storage mechanism for
> authenticate state is the session.  Because of #2, this will start a
> session validation thread.
>
> So by #2 and #3, if you create a SecurityManager for every
> authentication, therefore, you'll create a session validation thread
> for each authentication! (Thanks to Tamás for the hint).  So again,
> permission checks don't create threads at all - what you're seeing is
> an unrelated issue due to creating a new SecurityManager every time.
>
> Here's what I'd do in your scenario:
>
> - Create one and only one SecurityManager.  Set it on
> SecurityUtils.setSecurityManager if you have to to ensure it is
> re-used (although this is not recommended - you would ideally use
> something like dependency injection or a configuration mechanism of
> your choice that manages application singletons without using static
> memory).
>
> - Don't create DelegatingSubject instances.  Use the Subject.Builder
> if you have to create ad-hoc Subject instances.
>
> For example, (very similar to Christian's example):
>
> Subject subject = new
> Subject.Builder(SecurityUtils.getSecurityManager()).buildSubject();
> subject.login(usernamePasswordToken);
> if (subject.isPermitted(whatever)) {
>     do something
> }
>
> Because you built the subject manually (and didn't use
> SecurityUtils.getSubject()), the built subject is _not_ bound to the
> current thread, so other calls to SecurityUtils.getSubject() will not
> return the same Subject.  If you manually create Subject instances in
> Shiro, you are responsible for ensuring thread association if you wish
> to use SecurityUtils.getSubject() in other parts of your code.
>
> HTH,
>
> --
> Les Hazlewood | @lhazlewood
> CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282
>
>
> On Wed, May 15, 2013 at 7:47 AM, Tamás Cservenák <ta...@cservenak.net> wrote:
>> Session validating thread....?
>>
>> but by looking at the code, um, very strange use of Shiro.. :)
>>
>>
>> On Wed, May 15, 2013 at 4:14 PM, ApacheNinja <dp...@gmail.com> wrote:
>>>
>>> Hello,
>>>
>>> Yes, we are using the latest release of Shiro.   We are primarily using
>>> Shiro to check user permissions.  We are not using it to log in to our
>>> application.  We are creating our Subject using the following method:
>>>
>>> protected void setAuthorizerSubject(UsersDVO user){
>>>         DefaultSecurityManager securityManager = new
>>> DefaultSecurityManager();
>>>         securityManager.setRealm(realm);
>>>         securityManager.setAuthenticator(new MockAuthenticator());
>>>         SecurityUtils.setSecurityManager(securityManager );
>>>         Subject currentUser = new DelegatingSubject(securityManager);
>>>         if(!currentUser.isAuthenticated()){
>>>             UsernamePasswordToken token = new
>>> UsernamePasswordToken(user.getUserName(), "");
>>>             try{
>>>                 currentUser.login(token);
>>>             } catch (AuthenticationException ex){
>>>                 Log.exception(ex);
>>>             }
>>>         }
>>>         this.subject = currentUser;
>>>     }
>>>
>>> This is created once when the user logs in.  In our application it is
>>> possible to log in as a general administrator first, then log in again as
>>> a
>>> more specific user.  So this may be called twice.  We then use the Subject
>>> object to call the isPermitted() object, which checks to see if the user
>>> has
>>> access to different portions of our application.  In our Realm object we
>>> have set setAuthorizationCachingEnabled(false) (I don't think this makes a
>>> difference but I thought I would include this information anyway).
>>> Looking
>>> at the stack trace when calling isPermitted(), I see that it goes through
>>> the Shiro API and then it then calls our implementation
>>> doGetAuthorizationInfo() :
>>>
>>>     @Override
>>>     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection
>>> principalCollection) {
>>>         SimpleAuthorizationInfo info = null;
>>>         if( user != null ) {
>>>             info = new SimpleAuthorizationInfo();
>>>             List<Role> roles =
>>> roleManager.getRolesForUser(user.getUserID());
>>>             List<EPermission> permissions =
>>> permissionManager.getPermissionsForUser(user.getUserID());
>>>             for(Role role : roles) {
>>>                 info.addRole(role.getName());
>>>             }
>>>             for(EPermission permission : permissions){
>>>                 info.addStringPermission(permission.getName());
>>>             }
>>>         }
>>>
>>>         return info;
>>>     }
>>>
>>> Somewhere in there a new thread is being generated but I don't know where.
>>>
>>>
>>>
>>> --
>>> View this message in context:
>>> http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725p7578734.html
>>> Sent from the Shiro User mailing list archive at Nabble.com.
>>
>>

Re: Too many threads created when calling isPermitted()

Posted by Les Hazlewood <lh...@apache.org>.
Shiro does not create threads for permission checks.  What you're
seeing is a side-effect of non-standard Shiro usage.

It is expected that you (or a config mechanism like shiro.ini or
Spring or Guice, etc) create one and only one SecurityManager instance
for your entire application.  Additionally, DelegatingSubject is an
internal implementation class in Shiro - it shouldn't be used directly
by application code (it only might ever be used by non-Shiro
developers if they are writing framework-integration code for Shiro -
not for standard app use cases).  If you need to create ad-hoc Subject
instances, you should use the Subject.Builder to create ad-hoc Subject
instances, passing in the SecurityManager as a constructor argument.

In any event, here is what you are seeing:

1.  Shiro's default SecurityManager implementation has an internal
SessionManager.
2.  This SessionManager, if sessions are used, will create a session
validation thread (to ensure that orphaned sessions can be cleaned
properly).
3.  If you authenticate a user, Shiro's default storage mechanism for
authenticate state is the session.  Because of #2, this will start a
session validation thread.

So by #2 and #3, if you create a SecurityManager for every
authentication, therefore, you'll create a session validation thread
for each authentication! (Thanks to Tamás for the hint).  So again,
permission checks don't create threads at all - what you're seeing is
an unrelated issue due to creating a new SecurityManager every time.

Here's what I'd do in your scenario:

- Create one and only one SecurityManager.  Set it on
SecurityUtils.setSecurityManager if you have to to ensure it is
re-used (although this is not recommended - you would ideally use
something like dependency injection or a configuration mechanism of
your choice that manages application singletons without using static
memory).

- Don't create DelegatingSubject instances.  Use the Subject.Builder
if you have to create ad-hoc Subject instances.

For example, (very similar to Christian's example):

Subject subject = new
Subject.Builder(SecurityUtils.getSecurityManager()).buildSubject();
subject.login(usernamePasswordToken);
if (subject.isPermitted(whatever)) {
    do something
}

Because you built the subject manually (and didn't use
SecurityUtils.getSubject()), the built subject is _not_ bound to the
current thread, so other calls to SecurityUtils.getSubject() will not
return the same Subject.  If you manually create Subject instances in
Shiro, you are responsible for ensuring thread association if you wish
to use SecurityUtils.getSubject() in other parts of your code.

HTH,

--
Les Hazlewood | @lhazlewood
CTO, Stormpath | http://stormpath.com | @goStormpath | 888.391.5282


On Wed, May 15, 2013 at 7:47 AM, Tamás Cservenák <ta...@cservenak.net> wrote:
> Session validating thread....?
>
> but by looking at the code, um, very strange use of Shiro.. :)
>
>
> On Wed, May 15, 2013 at 4:14 PM, ApacheNinja <dp...@gmail.com> wrote:
>>
>> Hello,
>>
>> Yes, we are using the latest release of Shiro.   We are primarily using
>> Shiro to check user permissions.  We are not using it to log in to our
>> application.  We are creating our Subject using the following method:
>>
>> protected void setAuthorizerSubject(UsersDVO user){
>>         DefaultSecurityManager securityManager = new
>> DefaultSecurityManager();
>>         securityManager.setRealm(realm);
>>         securityManager.setAuthenticator(new MockAuthenticator());
>>         SecurityUtils.setSecurityManager(securityManager );
>>         Subject currentUser = new DelegatingSubject(securityManager);
>>         if(!currentUser.isAuthenticated()){
>>             UsernamePasswordToken token = new
>> UsernamePasswordToken(user.getUserName(), "");
>>             try{
>>                 currentUser.login(token);
>>             } catch (AuthenticationException ex){
>>                 Log.exception(ex);
>>             }
>>         }
>>         this.subject = currentUser;
>>     }
>>
>> This is created once when the user logs in.  In our application it is
>> possible to log in as a general administrator first, then log in again as
>> a
>> more specific user.  So this may be called twice.  We then use the Subject
>> object to call the isPermitted() object, which checks to see if the user
>> has
>> access to different portions of our application.  In our Realm object we
>> have set setAuthorizationCachingEnabled(false) (I don't think this makes a
>> difference but I thought I would include this information anyway).
>> Looking
>> at the stack trace when calling isPermitted(), I see that it goes through
>> the Shiro API and then it then calls our implementation
>> doGetAuthorizationInfo() :
>>
>>     @Override
>>     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection
>> principalCollection) {
>>         SimpleAuthorizationInfo info = null;
>>         if( user != null ) {
>>             info = new SimpleAuthorizationInfo();
>>             List<Role> roles =
>> roleManager.getRolesForUser(user.getUserID());
>>             List<EPermission> permissions =
>> permissionManager.getPermissionsForUser(user.getUserID());
>>             for(Role role : roles) {
>>                 info.addRole(role.getName());
>>             }
>>             for(EPermission permission : permissions){
>>                 info.addStringPermission(permission.getName());
>>             }
>>         }
>>
>>         return info;
>>     }
>>
>> Somewhere in there a new thread is being generated but I don't know where.
>>
>>
>>
>> --
>> View this message in context:
>> http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725p7578734.html
>> Sent from the Shiro User mailing list archive at Nabble.com.
>
>

Re: Too many threads created when calling isPermitted()

Posted by Tamás Cservenák <ta...@cservenak.net>.
Session validating thread....?

but by looking at the code, um, very strange use of Shiro.. :)


On Wed, May 15, 2013 at 4:14 PM, ApacheNinja <dp...@gmail.com> wrote:

> Hello,
>
> Yes, we are using the latest release of Shiro.   We are primarily using
> Shiro to check user permissions.  We are not using it to log in to our
> application.  We are creating our Subject using the following method:
>
> protected void setAuthorizerSubject(UsersDVO user){
>         DefaultSecurityManager securityManager = new
> DefaultSecurityManager();
>         securityManager.setRealm(realm);
>         securityManager.setAuthenticator(new MockAuthenticator());
>         SecurityUtils.setSecurityManager(securityManager );
>         Subject currentUser = new DelegatingSubject(securityManager);
>         if(!currentUser.isAuthenticated()){
>             UsernamePasswordToken token = new
> UsernamePasswordToken(user.getUserName(), "");
>             try{
>                 currentUser.login(token);
>             } catch (AuthenticationException ex){
>                 Log.exception(ex);
>             }
>         }
>         this.subject = currentUser;
>     }
>
> This is created once when the user logs in.  In our application it is
> possible to log in as a general administrator first, then log in again as a
> more specific user.  So this may be called twice.  We then use the Subject
> object to call the isPermitted() object, which checks to see if the user
> has
> access to different portions of our application.  In our Realm object we
> have set setAuthorizationCachingEnabled(false) (I don't think this makes a
> difference but I thought I would include this information anyway).  Looking
> at the stack trace when calling isPermitted(), I see that it goes through
> the Shiro API and then it then calls our implementation
> doGetAuthorizationInfo() :
>
>     @Override
>     protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection
> principalCollection) {
>         SimpleAuthorizationInfo info = null;
>         if( user != null ) {
>             info = new SimpleAuthorizationInfo();
>             List<Role> roles =
> roleManager.getRolesForUser(user.getUserID());
>             List<EPermission> permissions =
> permissionManager.getPermissionsForUser(user.getUserID());
>             for(Role role : roles) {
>                 info.addRole(role.getName());
>             }
>             for(EPermission permission : permissions){
>                 info.addStringPermission(permission.getName());
>             }
>         }
>
>         return info;
>     }
>
> Somewhere in there a new thread is being generated but I don't know where.
>
>
>
> --
> View this message in context:
> http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725p7578734.html
> Sent from the Shiro User mailing list archive at Nabble.com.
>

RE: Too many threads created when calling isPermitted()

Posted by Poitras Christian <Ch...@ircm.qc.ca>.
Hi,

I think this a configuration issue.
Only one security manager should be created in your application. In a standalone app, it would be in the main method. In a web application, it would be in a ServletContextListener.
Then you can access the subject in your application using SecurityUtils.getSubject().

So to login a user, you may do something like :
        Subject currentUser = SecurityUtils.getSubject();
        if(!currentUser.isAuthenticated()){
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), "");
            try{
                currentUser.login(token);
            } catch (AuthenticationException ex){
                Log.exception(ex);
            }
        }

To allow an admin to run the application as another user, simply do this :
       Subject currentUser = SecurityUtils.getSubject();
	PrincipalCollection principals = new SimplePrincipalCollection(specificUserPrincipal, realmName);
	subject.runAs(principals);

Christian

-----Message d'origine-----
De : ApacheNinja [mailto:dpryce7@gmail.com] 
Envoyé : May-15-13 10:15 AM
À : user@shiro.apache.org
Objet : RE: Too many threads created when calling isPermitted()

Hello,

Yes, we are using the latest release of Shiro.   We are primarily using
Shiro to check user permissions.  We are not using it to log in to our application.  We are creating our Subject using the following method:

protected void setAuthorizerSubject(UsersDVO user){
        DefaultSecurityManager securityManager = new DefaultSecurityManager();
        securityManager.setRealm(realm);
        securityManager.setAuthenticator(new MockAuthenticator());
        SecurityUtils.setSecurityManager(securityManager );
        Subject currentUser = new DelegatingSubject(securityManager);
        if(!currentUser.isAuthenticated()){
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), "");
            try{
                currentUser.login(token);
            } catch (AuthenticationException ex){
                Log.exception(ex);
            }
        }
        this.subject = currentUser;
    }

This is created once when the user logs in.  In our application it is possible to log in as a general administrator first, then log in again as a more specific user.  So this may be called twice.  We then use the Subject object to call the isPermitted() object, which checks to see if the user has access to different portions of our application.  In our Realm object we have set setAuthorizationCachingEnabled(false) (I don't think this makes a difference but I thought I would include this information anyway).  Looking at the stack trace when calling isPermitted(), I see that it goes through the Shiro API and then it then calls our implementation
doGetAuthorizationInfo() :

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection
principalCollection) {
        SimpleAuthorizationInfo info = null;
        if( user != null ) {
            info = new SimpleAuthorizationInfo();
            List<Role> roles =
roleManager.getRolesForUser(user.getUserID());
            List<EPermission> permissions = permissionManager.getPermissionsForUser(user.getUserID());
            for(Role role : roles) {
                info.addRole(role.getName());
            }
            for(EPermission permission : permissions){
                info.addStringPermission(permission.getName());
            }
        }

        return info;
    }

Somewhere in there a new thread is being generated but I don't know where.



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725p7578734.html
Sent from the Shiro User mailing list archive at Nabble.com.

RE: Too many threads created when calling isPermitted()

Posted by ApacheNinja <dp...@gmail.com>.
Hello,

Yes, we are using the latest release of Shiro.   We are primarily using
Shiro to check user permissions.  We are not using it to log in to our
application.  We are creating our Subject using the following method:

protected void setAuthorizerSubject(UsersDVO user){
        DefaultSecurityManager securityManager = new
DefaultSecurityManager();
        securityManager.setRealm(realm);
        securityManager.setAuthenticator(new MockAuthenticator());
        SecurityUtils.setSecurityManager(securityManager );
        Subject currentUser = new DelegatingSubject(securityManager);
        if(!currentUser.isAuthenticated()){
            UsernamePasswordToken token = new
UsernamePasswordToken(user.getUserName(), "");
            try{
                currentUser.login(token);
            } catch (AuthenticationException ex){
                Log.exception(ex);
            }
        }
        this.subject = currentUser;
    }

This is created once when the user logs in.  In our application it is
possible to log in as a general administrator first, then log in again as a
more specific user.  So this may be called twice.  We then use the Subject
object to call the isPermitted() object, which checks to see if the user has
access to different portions of our application.  In our Realm object we
have set setAuthorizationCachingEnabled(false) (I don't think this makes a
difference but I thought I would include this information anyway).  Looking
at the stack trace when calling isPermitted(), I see that it goes through
the Shiro API and then it then calls our implementation
doGetAuthorizationInfo() :

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection
principalCollection) {
        SimpleAuthorizationInfo info = null;
        if( user != null ) {
            info = new SimpleAuthorizationInfo();
            List<Role> roles =
roleManager.getRolesForUser(user.getUserID());
            List<EPermission> permissions =
permissionManager.getPermissionsForUser(user.getUserID());
            for(Role role : roles) {
                info.addRole(role.getName());
            }
            for(EPermission permission : permissions){
                info.addStringPermission(permission.getName());
            }
        }

        return info;
    }

Somewhere in there a new thread is being generated but I don't know where.



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725p7578734.html
Sent from the Shiro User mailing list archive at Nabble.com.

RE: Too many threads created when calling isPermitted()

Posted by Poitras Christian <Ch...@ircm.qc.ca>.
Hi,

What so you mean by "our implementation of Shiro"? Do you use an official release or do you use a custom implementation?
If you use a custom implementation but don't provide the source code, no one can help you.

Christian

-----Message d'origine-----
De : ApacheNinja [mailto:dpryce7@gmail.com] 
Envoyé : May-14-13 9:47 PM
À : user@shiro.apache.org
Objet : Too many threads created when calling isPermitted()

We are noticing in our implementation of Shiro that every time a user logs in a new thread is created.  We also notice that when permissions are being checked via the isPermitted() method (on the DelegatingSubject object) a new
thread is also created.   Our code has not been put in production yet where
there are a lot of users, however, we suspect the server will crash if we do.  Has anybody ran into this issue before?  How do Shiro threads work when calling the isPermitted() method?  Thank you in advance.



--
View this message in context: http://shiro-user.582556.n2.nabble.com/Too-many-threads-created-when-calling-isPermitted-tp7578725.html
Sent from the Shiro User mailing list archive at Nabble.com.