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);