Skip to content

Commit

Permalink
Security session validation periodic check
Browse files Browse the repository at this point in the history
  • Loading branch information
adrienlauer committed Aug 3, 2018
1 parent a9cd40c commit 4700454
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* [chg] X509-based authentication will use the subject `X500Principal` as identity if no `uid` attribute is available (instead of the whole chain).
* [chg] X509-based authentication will use the subject certificate (first in the chain) as credentials (instead of the whole chain).
* [new] X509-based authentication will now (re-)check the subject certificate validity.
* [new] Enable security session periodic validation (expiration check) when outside a Servlet environment.
* [chg] Authorization cache will now use the primary principal as key.

# Version 3.6.2 (2018-06-18)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.shiro.mgt.SessionStorageEvaluator;
import org.apache.shiro.mgt.SubjectDAO;
import org.apache.shiro.mgt.SubjectFactory;
import org.apache.shiro.session.mgt.SessionValidationScheduler;
import org.apache.shiro.subject.SubjectContext;
import org.seedstack.coffig.Config;
import org.seedstack.coffig.SingleValue;
Expand Down Expand Up @@ -162,7 +163,9 @@ public static class SessionConfig {
@SingleValue
private boolean enabled = true;
private long timeout = 1000 * 60 * 15;
private long validationInterval = timeout / 2;
private Class<? extends SessionStorageEvaluator> storageEvaluator = SeedSessionStorageEvaluator.class;
private Class<? extends SessionValidationScheduler> validationScheduler;

public boolean isEnabled() {
return enabled;
Expand Down Expand Up @@ -190,6 +193,25 @@ public SessionConfig setStorageEvaluator(Class<? extends SessionStorageEvaluator
this.storageEvaluator = storageEvaluator;
return this;
}

public Class<? extends SessionValidationScheduler> getValidationScheduler() {
return validationScheduler;
}

public SessionConfig setValidationScheduler(
Class<? extends SessionValidationScheduler> validationScheduler) {
this.validationScheduler = validationScheduler;
return this;
}

public long getValidationInterval() {
return validationInterval;
}

public SessionConfig setValidationInterval(long validationInterval) {
this.validationInterval = validationInterval;
return this;
}
}

@Config("subject")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import org.apache.shiro.mgt.SessionStorageEvaluator;
import org.apache.shiro.mgt.SubjectDAO;
import org.apache.shiro.mgt.SubjectFactory;
import org.apache.shiro.session.mgt.SessionValidationScheduler;
import org.apache.shiro.subject.SubjectContext;
import org.seedstack.seed.security.SecurityConfig;

Expand Down Expand Up @@ -50,6 +51,11 @@ public void configure(Binder binder) {
// Sessions
SecurityConfig.SessionConfig sessionConfig = securityConfig.sessions();
binder.bind(SessionStorageEvaluator.class).to(sessionConfig.getStorageEvaluator());
Optional.ofNullable(sessionConfig.getValidationScheduler())
.ifPresent(s -> binder.bind(SessionValidationScheduler.class).to(s));
binder.bindConstant()
.annotatedWith(Names.named("shiro.sessionValidationInterval"))
.to(sessionConfig.getValidationInterval());
binder.bindConstant()
.annotatedWith(Names.named("shiro.globalSessionTimeout"))
.to(sessionConfig.getTimeout());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,24 @@ protected Object getAuthenticationCacheKey(PrincipalCollection principals) {

@Override
protected Object getAuthorizationCacheKey(PrincipalCollection principals) {
Object authenticationCacheKey = super.getAuthenticationCacheKey(principals);
if (authenticationCacheKey instanceof PrincipalProvider) {
return ((PrincipalProvider) authenticationCacheKey).getPrincipal();
Object primaryPrincipal = principals.getPrimaryPrincipal();
if (primaryPrincipal instanceof PrincipalProvider) {
return ((PrincipalProvider) primaryPrincipal).getPrincipal();
} else {
return authenticationCacheKey;
return primaryPrincipal;
}
}

@Override
public String getAuthenticationCacheName() {
return realm.getClass().getName() + ".authenticationCache";
}

@Override
public String getAuthorizationCacheName() {
return realm.getClass().getName() + ".authorizationCache";
}

Realm getRealm() {
return realm;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

package org.seedstack.seed.security.fixtures;

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

@Override
public V get(K key) throws CacheException {
logger.info("Getting {} from {} security cache", key, name);
assertKeyClass(key);
return super.get(key);
V v = super.get(key);
if (v == null) {
logger.info("Nothing found for key {} in security cache {}", key, name);
} else {
logger.info("Info found for key {} in security cache {}", key, name);
}
return v;
}

@Override
public V put(K key, V value) throws CacheException {
logger.info("Putting {} / {} in {} security cache", key, value, name);
logger.info("Putting {} in security cache {}", key, name);
assertKeyClass(key);
return super.put(key, value);
}

@Override
public V remove(K key) throws CacheException {
logger.info("Removing {} from {} security cache", key, name);
assertKeyClass(key);
return super.remove(key);
V v = super.remove(key);
if (v == null) {
logger.info("Nothing was removed for key {} from security cache {}", name);
} else {
logger.info("{} was removed from security cache {}", key, name);
}
return v;
}

private synchronized void assertKeyClass(K key) {
Expand Down

0 comments on commit 4700454

Please sign in to comment.