You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2019/08/02 15:31:20 UTC

[isis] branch v2 updated: ISIS-2156 enables smoketest for stress-testing the restful endpoint

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch v2
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/v2 by this push:
     new b569af4  ISIS-2156 enables smoketest for stress-testing the restful endpoint
b569af4 is described below

commit b569af48c477aee93e1a4f9032a2d26aa0ffaca4
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Aug 2 17:31:11 2019 +0200

    ISIS-2156 enables smoketest for stress-testing the restful endpoint
    
    - we now have the infrastructure to reproduce the memory leak issue
    - also adds an optimization to the IsisModuleSecurityRealm, to not
    authenticate a user twice per request
    
    findings so far, PrincipalForApplicationUser indeed does not get garbage
    collected
---
 .../shiro/ShiroSecmanLdap_restfulStressTest.java   | 21 +++------
 .../test/resources/shiro-secman-ldap-cached.ini    | 55 ++++++++++++++++++++++
 .../secman/shiro/IsisModuleSecurityRealm.java      | 21 +++++++++
 3 files changed, 83 insertions(+), 14 deletions(-)

diff --git a/examples/smoketests/src/test/java/org/apache/isis/testdomain/shiro/ShiroSecmanLdap_restfulStressTest.java b/examples/smoketests/src/test/java/org/apache/isis/testdomain/shiro/ShiroSecmanLdap_restfulStressTest.java
index 377548c..edae740 100644
--- a/examples/smoketests/src/test/java/org/apache/isis/testdomain/shiro/ShiroSecmanLdap_restfulStressTest.java
+++ b/examples/smoketests/src/test/java/org/apache/isis/testdomain/shiro/ShiroSecmanLdap_restfulStressTest.java
@@ -79,13 +79,8 @@ class ShiroSecmanLdap_restfulStressTest extends AbstractShiroTest {
 
     @BeforeAll
     static void beforeClass() {
-        //    Build and set the SecurityManager used to build Subject instances used in your tests
-        //    This typically only needs to be done once per class if your shiro.ini doesn't change,
-        //    otherwise, you'll need to do this logic in each test that is different
-        //val factory = new IniSecurityManagerFactory("classpath:shiro-secman-ldap.ini");
-        //setSecurityManager(factory.getInstance());
+        //WebModuleShiro.setShiroIniResource("classpath:shiro-secman-ldap-cached.ini");
         WebModuleShiro.setShiroIniResource("classpath:shiro-secman-ldap.ini");
-
     }
 
     @AfterAll
@@ -108,19 +103,17 @@ class ShiroSecmanLdap_restfulStressTest extends AbstractShiroTest {
     }
 
     @Test
-    void bookOfTheWeek_viaRestEndpoint() {
-
-        //TODO not very stressfull yet
+    void stressTheRestEndpoint() {
 
         val useRequestDebugLogging = false;
         val restfulClient = restService.newClient(useRequestDebugLogging);
 
-        val digest = restService.getRecommendedBookOfTheWeek(restfulClient);
-
-        if(!digest.isSuccess()) {
-            fail(digest.getFailureCause());
+        for(int i=0; i<100; ++i) {
+            val digest = restService.getRecommendedBookOfTheWeek(restfulClient);
+            if(!digest.isSuccess()) {
+                fail(digest.getFailureCause());
+            }
         }
-
     }
 
 }
diff --git a/examples/smoketests/src/test/resources/shiro-secman-ldap-cached.ini b/examples/smoketests/src/test/resources/shiro-secman-ldap-cached.ini
new file mode 100644
index 0000000..f6ad033
--- /dev/null
+++ b/examples/smoketests/src/test/resources/shiro-secman-ldap-cached.ini
@@ -0,0 +1,55 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+[main]
+
+contextFactory = org.apache.isis.security.shiro.IsisLdapContextFactory
+contextFactory.url = ldap://localhost:10389
+contextFactory.authenticationMechanism = simple
+contextFactory.systemAuthenticationMechanism = simple
+contextFactory.systemUsername = uid=admin,ou=system
+contextFactory.systemPassword = secret
+
+ldapRealm = org.apache.isis.security.shiro.IsisLdapRealm   
+ldapRealm.contextFactory = $contextFactory
+ldapRealm.searchBase = ou=groups,o=mojo                    
+ldapRealm.groupObjectClass = groupOfUniqueNames            
+ldapRealm.uniqueMemberAttribute = uniqueMember             
+ldapRealm.uniqueMemberAttributeValueTemplate = uid={0}
+
+authenticationStrategy=org.apache.isis.extensions.secman.shiro.AuthenticationStrategyForIsisModuleSecurityRealm
+isisModuleSecurityRealm=org.apache.isis.extensions.secman.shiro.IsisModuleSecurityRealm
+isisModuleSecurityRealm.delegateAuthenticationRealm=$ldapRealm
+isisModuleSecurityRealm.authenticationCachingEnabled = true
+
+cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
+
+securityManager.authenticator.authenticationStrategy = $authenticationStrategy
+securityManager.realms = $isisModuleSecurityRealm
+securityManager.cacheManager = $cacheManager
+
+[users]
+# unused
+
+[roles]
+# unused
+
+
+
+
diff --git a/extensions/secman/realm-shiro/src/main/java/org/apache/isis/extensions/secman/shiro/IsisModuleSecurityRealm.java b/extensions/secman/realm-shiro/src/main/java/org/apache/isis/extensions/secman/shiro/IsisModuleSecurityRealm.java
index a753653..8ba458e 100644
--- a/extensions/secman/realm-shiro/src/main/java/org/apache/isis/extensions/secman/shiro/IsisModuleSecurityRealm.java
+++ b/extensions/secman/realm-shiro/src/main/java/org/apache/isis/extensions/secman/shiro/IsisModuleSecurityRealm.java
@@ -24,6 +24,7 @@ import java.util.function.Supplier;
 
 import javax.inject.Inject;
 
+import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.AuthenticationInfo;
 import org.apache.shiro.authc.AuthenticationToken;
@@ -79,6 +80,26 @@ public class IsisModuleSecurityRealm extends AuthorizingRealm implements Securit
         val usernamePasswordToken = (UsernamePasswordToken) token;
         val username = usernamePasswordToken.getUsername();
         val password = usernamePasswordToken.getPassword();
+        
+
+        // this code block is just an optimization, entirely optional
+        // we reuse principal information on subjects that are already authenticated
+        {
+            val currentSubject = SecurityUtils.getSubject();
+            if(currentSubject!=null && currentSubject.isAuthenticated()) {
+                val authenticatedPrincipalObject = currentSubject.getPrincipal();
+                if(authenticatedPrincipalObject instanceof PrincipalForApplicationUser) {
+                    val authenticatedPrincipal = (PrincipalForApplicationUser) authenticatedPrincipalObject;
+                    val authenticatedUsername = authenticatedPrincipal.getUsername();
+                    val isAuthenticatedWithThisRealm = username.equals(authenticatedUsername);
+                    if(isAuthenticatedWithThisRealm) {
+                        val credentials = token.getCredentials();
+                        val realmName = getName();
+                        return new AuthInfoForApplicationUser(authenticatedPrincipal, realmName, credentials);                        
+                    }
+                }
+            }
+        }
 
         // lookup from database, for roles/perms
         val principal = lookupPrincipal_inApplicationUserRepository(username);