Skip to content

Commit b5ab7e4

Browse files
committed
Fix bad authentication cache invalidation
1 parent aab1b62 commit b5ab7e4

File tree

4 files changed

+109
-7
lines changed

4 files changed

+109
-7
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
# Version 3.6.2 (2018-06-15)
1+
# Version 3.6.2 (2018-06-18)
22

33
* [chg] Also support proxy exclusions without wildcard (`*.somedomain.com`, `.somedomain.com` and `somedomain.com` are all supported).
44
* [chg] Moved provided `javax.annotation.Nullable` to `org.seedstack.seed.Nullable` to avoid module clashes in Java 9+.
55
* [chg] Various dependency improvements for Java9+ modules.
66
* [fix] Prevent the session regeneration mechanism to create a session when none exists.
7+
* [fix] Fix bug preventing proper invalidation of the Shiro authentication cache.
78

89
# Version 3.6.1 (2018-06-06)
910

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

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,42 @@ protected AuthenticationInfo doGetAuthenticationInfo(
106106
return authcInfo;
107107
}
108108

109+
@Override
110+
public boolean supports(AuthenticationToken token) {
111+
org.seedstack.seed.security.AuthenticationToken seedToken = convertToken(token);
112+
return seedToken != null && realm.supportedToken().isAssignableFrom(seedToken.getClass());
113+
}
114+
115+
@Override
116+
protected Object getAuthenticationCacheKey(AuthenticationToken token) {
117+
Object authenticationCacheKey = super.getAuthenticationCacheKey(token);
118+
if (authenticationCacheKey instanceof PrincipalProvider) {
119+
return ((PrincipalProvider) authenticationCacheKey).getPrincipal();
120+
} else {
121+
return authenticationCacheKey;
122+
}
123+
}
124+
125+
@Override
126+
protected Object getAuthenticationCacheKey(PrincipalCollection principals) {
127+
Object authenticationCacheKey = super.getAuthenticationCacheKey(principals);
128+
if (authenticationCacheKey instanceof PrincipalProvider) {
129+
return ((PrincipalProvider) authenticationCacheKey).getPrincipal();
130+
} else {
131+
return authenticationCacheKey;
132+
}
133+
}
134+
135+
@Override
136+
protected Object getAuthorizationCacheKey(PrincipalCollection principals) {
137+
Object authenticationCacheKey = super.getAuthenticationCacheKey(principals);
138+
if (authenticationCacheKey instanceof PrincipalProvider) {
139+
return ((PrincipalProvider) authenticationCacheKey).getPrincipal();
140+
} else {
141+
return authenticationCacheKey;
142+
}
143+
}
144+
109145
Realm getRealm() {
110146
return realm;
111147
}
@@ -114,12 +150,6 @@ void setRealm(Realm realm) {
114150
this.realm = realm;
115151
}
116152

117-
@Override
118-
public boolean supports(AuthenticationToken token) {
119-
org.seedstack.seed.security.AuthenticationToken seedToken = convertToken(token);
120-
return seedToken != null && realm.supportedToken().isAssignableFrom(seedToken.getClass());
121-
}
122-
123153
private org.seedstack.seed.security.AuthenticationToken convertToken(AuthenticationToken token) {
124154
if (token instanceof org.seedstack.seed.security.AuthenticationToken) {
125155
return (org.seedstack.seed.security.AuthenticationToken) token;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright © 2013-2018, The SeedStack authors <http://seedstack.org>
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*/
8+
package org.seedstack.seed.security.fixtures;
9+
10+
import static org.assertj.core.api.Assertions.assertThat;
11+
12+
import java.util.HashMap;
13+
import java.util.Map;
14+
import org.apache.shiro.cache.AbstractCacheManager;
15+
import org.apache.shiro.cache.Cache;
16+
import org.apache.shiro.cache.CacheException;
17+
import org.apache.shiro.cache.MapCache;
18+
import org.seedstack.seed.Logging;
19+
import org.slf4j.Logger;
20+
21+
public class TestCacheManager extends AbstractCacheManager {
22+
@Logging
23+
private Logger logger;
24+
25+
@Override
26+
@SuppressWarnings("unchecked")
27+
protected Cache createCache(String s) throws CacheException {
28+
return new TestCache(s, new HashMap());
29+
}
30+
31+
private class TestCache<K, V> extends MapCache<K, V> {
32+
private final String name;
33+
private Class<?> keyType;
34+
35+
TestCache(String name, Map<K, V> backingMap) {
36+
super(name, backingMap);
37+
this.name = name;
38+
}
39+
40+
@Override
41+
public V get(K key) throws CacheException {
42+
logger.info("Getting {} from {} security cache", key, name);
43+
assertKeyClass(key);
44+
return super.get(key);
45+
}
46+
47+
@Override
48+
public V put(K key, V value) throws CacheException {
49+
logger.info("Putting {} / {} in {} security cache", key, value, name);
50+
assertKeyClass(key);
51+
return super.put(key, value);
52+
}
53+
54+
@Override
55+
public V remove(K key) throws CacheException {
56+
logger.info("Removing {} from {} security cache", key, name);
57+
assertKeyClass(key);
58+
return super.remove(key);
59+
}
60+
61+
private synchronized void assertKeyClass(K key) {
62+
if (keyType == null) {
63+
keyType = key.getClass();
64+
} else {
65+
assertThat(key).isOfAnyClassIn(keyType);
66+
}
67+
}
68+
}
69+
}

security/core/src/test/resources/application.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
logging: INFO
1010
security:
1111
realms: ConfigurationRealm
12+
cache:
13+
manager: org.seedstack.seed.security.fixtures.TestCacheManager
1214
users:
1315
Obiwan:
1416
password: yodarulez

0 commit comments

Comments
 (0)