Skip to content

Commit 4700454

Browse files
committed
Security session validation periodic check
1 parent a9cd40c commit 4700454

File tree

5 files changed

+60
-9
lines changed

5 files changed

+60
-9
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
* [chg] X509-based authentication will use the subject `X500Principal` as identity if no `uid` attribute is available (instead of the whole chain).
66
* [chg] X509-based authentication will use the subject certificate (first in the chain) as credentials (instead of the whole chain).
77
* [new] X509-based authentication will now (re-)check the subject certificate validity.
8+
* [new] Enable security session periodic validation (expiration check) when outside a Servlet environment.
9+
* [chg] Authorization cache will now use the primary principal as key.
810

911
# Version 3.6.2 (2018-06-18)
1012

security/core/src/main/java/org/seedstack/seed/security/SecurityConfig.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.shiro.mgt.SessionStorageEvaluator;
2828
import org.apache.shiro.mgt.SubjectDAO;
2929
import org.apache.shiro.mgt.SubjectFactory;
30+
import org.apache.shiro.session.mgt.SessionValidationScheduler;
3031
import org.apache.shiro.subject.SubjectContext;
3132
import org.seedstack.coffig.Config;
3233
import org.seedstack.coffig.SingleValue;
@@ -162,7 +163,9 @@ public static class SessionConfig {
162163
@SingleValue
163164
private boolean enabled = true;
164165
private long timeout = 1000 * 60 * 15;
166+
private long validationInterval = timeout / 2;
165167
private Class<? extends SessionStorageEvaluator> storageEvaluator = SeedSessionStorageEvaluator.class;
168+
private Class<? extends SessionValidationScheduler> validationScheduler;
166169

167170
public boolean isEnabled() {
168171
return enabled;
@@ -190,6 +193,25 @@ public SessionConfig setStorageEvaluator(Class<? extends SessionStorageEvaluator
190193
this.storageEvaluator = storageEvaluator;
191194
return this;
192195
}
196+
197+
public Class<? extends SessionValidationScheduler> getValidationScheduler() {
198+
return validationScheduler;
199+
}
200+
201+
public SessionConfig setValidationScheduler(
202+
Class<? extends SessionValidationScheduler> validationScheduler) {
203+
this.validationScheduler = validationScheduler;
204+
return this;
205+
}
206+
207+
public long getValidationInterval() {
208+
return validationInterval;
209+
}
210+
211+
public SessionConfig setValidationInterval(long validationInterval) {
212+
this.validationInterval = validationInterval;
213+
return this;
214+
}
193215
}
194216

195217
@Config("subject")

security/core/src/main/java/org/seedstack/seed/security/internal/SecurityGuiceConfigurer.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.apache.shiro.mgt.SessionStorageEvaluator;
2020
import org.apache.shiro.mgt.SubjectDAO;
2121
import org.apache.shiro.mgt.SubjectFactory;
22+
import org.apache.shiro.session.mgt.SessionValidationScheduler;
2223
import org.apache.shiro.subject.SubjectContext;
2324
import org.seedstack.seed.security.SecurityConfig;
2425

@@ -50,6 +51,11 @@ public void configure(Binder binder) {
5051
// Sessions
5152
SecurityConfig.SessionConfig sessionConfig = securityConfig.sessions();
5253
binder.bind(SessionStorageEvaluator.class).to(sessionConfig.getStorageEvaluator());
54+
Optional.ofNullable(sessionConfig.getValidationScheduler())
55+
.ifPresent(s -> binder.bind(SessionValidationScheduler.class).to(s));
56+
binder.bindConstant()
57+
.annotatedWith(Names.named("shiro.sessionValidationInterval"))
58+
.to(sessionConfig.getValidationInterval());
5359
binder.bindConstant()
5460
.annotatedWith(Names.named("shiro.globalSessionTimeout"))
5561
.to(sessionConfig.getTimeout());

security/core/src/main/java/org/seedstack/seed/security/internal/ShiroRealmAdapter.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,24 @@ protected Object getAuthenticationCacheKey(PrincipalCollection principals) {
132132

133133
@Override
134134
protected Object getAuthorizationCacheKey(PrincipalCollection principals) {
135-
Object authenticationCacheKey = super.getAuthenticationCacheKey(principals);
136-
if (authenticationCacheKey instanceof PrincipalProvider) {
137-
return ((PrincipalProvider) authenticationCacheKey).getPrincipal();
135+
Object primaryPrincipal = principals.getPrimaryPrincipal();
136+
if (primaryPrincipal instanceof PrincipalProvider) {
137+
return ((PrincipalProvider) primaryPrincipal).getPrincipal();
138138
} else {
139-
return authenticationCacheKey;
139+
return primaryPrincipal;
140140
}
141141
}
142142

143+
@Override
144+
public String getAuthenticationCacheName() {
145+
return realm.getClass().getName() + ".authenticationCache";
146+
}
147+
148+
@Override
149+
public String getAuthorizationCacheName() {
150+
return realm.getClass().getName() + ".authorizationCache";
151+
}
152+
143153
Realm getRealm() {
144154
return realm;
145155
}

security/core/src/test/java/org/seedstack/seed/security/fixtures/TestCacheManager.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* License, v. 2.0. If a copy of the MPL was not distributed with this
66
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
77
*/
8+
89
package org.seedstack.seed.security.fixtures;
910

1011
import static org.assertj.core.api.Assertions.assertThat;
@@ -39,23 +40,33 @@ private class TestCache<K, V> extends MapCache<K, V> {
3940

4041
@Override
4142
public V get(K key) throws CacheException {
42-
logger.info("Getting {} from {} security cache", key, name);
4343
assertKeyClass(key);
44-
return super.get(key);
44+
V v = super.get(key);
45+
if (v == null) {
46+
logger.info("Nothing found for key {} in security cache {}", key, name);
47+
} else {
48+
logger.info("Info found for key {} in security cache {}", key, name);
49+
}
50+
return v;
4551
}
4652

4753
@Override
4854
public V put(K key, V value) throws CacheException {
49-
logger.info("Putting {} / {} in {} security cache", key, value, name);
55+
logger.info("Putting {} in security cache {}", key, name);
5056
assertKeyClass(key);
5157
return super.put(key, value);
5258
}
5359

5460
@Override
5561
public V remove(K key) throws CacheException {
56-
logger.info("Removing {} from {} security cache", key, name);
5762
assertKeyClass(key);
58-
return super.remove(key);
63+
V v = super.remove(key);
64+
if (v == null) {
65+
logger.info("Nothing was removed for key {} from security cache {}", name);
66+
} else {
67+
logger.info("{} was removed from security cache {}", key, name);
68+
}
69+
return v;
5970
}
6071

6172
private synchronized void assertKeyClass(K key) {

0 commit comments

Comments
 (0)