From 512a1e887298c465a9be461471171fa42d18221b Mon Sep 17 00:00:00 2001 From: Diana Krepinska Date: Wed, 31 Aug 2022 19:04:31 +0200 Subject: [PATCH] [ELY-2413] Re-authentication after reboot, even though HttpSession are persisted --- .../org/wildfly/security/authz/Roles.java | 26 ++++++++++++ .../security/cache/CachedIdentity.java | 42 +++++++++++++++++++ .../http/impl/AbstractBaseHttpTest.java | 5 +++ 3 files changed, 73 insertions(+) diff --git a/auth/server/base/src/main/java/org/wildfly/security/authz/Roles.java b/auth/server/base/src/main/java/org/wildfly/security/authz/Roles.java index 43ba4a7bf8d..0e64039b3fc 100644 --- a/auth/server/base/src/main/java/org/wildfly/security/authz/Roles.java +++ b/auth/server/base/src/main/java/org/wildfly/security/authz/Roles.java @@ -20,11 +20,13 @@ import static org.wildfly.common.Assert.checkNotNullParam; import static org.wildfly.common.Assert.checkNotEmptyParam; + import java.util.Collections; import java.util.Iterator; import java.util.Set; import java.util.Spliterator; import java.util.Spliterators; +import java.util.TreeSet; import java.util.function.Consumer; import org.wildfly.common.Assert; @@ -130,6 +132,30 @@ public boolean isEmpty() { }; } + /** + * Returns a set (immutable) containing roles from a roles collection. + * + * @param roles collection (not {@code null}) + * @return the set of role names (must not be {@code null}) + */ + static Set toSet(Roles roles) { + Assert.checkNotNullParam("roles", roles); + Iterator iterator = roles.iterator(); + if (!iterator.hasNext()) { + return Collections.emptySet(); + } + String role = iterator.next(); + if (!iterator.hasNext()) { + return Collections.singleton(role); + } + Set result = new TreeSet<>(); + result.add(role); + while (iterator.hasNext()) { + result.add(iterator.next()); + } + return Collections.unmodifiableSet(result); + } + /** * Construct a role set consisting of a single role. * diff --git a/auth/server/base/src/main/java/org/wildfly/security/cache/CachedIdentity.java b/auth/server/base/src/main/java/org/wildfly/security/cache/CachedIdentity.java index b142ab0a520..822b91066f4 100644 --- a/auth/server/base/src/main/java/org/wildfly/security/cache/CachedIdentity.java +++ b/auth/server/base/src/main/java/org/wildfly/security/cache/CachedIdentity.java @@ -22,8 +22,11 @@ import java.io.Serializable; import java.security.Principal; +import java.util.Collections; +import java.util.Set; import org.wildfly.security.auth.server.SecurityIdentity; +import org.wildfly.security.authz.Roles; /** * Represents a cached identity, managed by an {@link IdentityCache}. @@ -41,6 +44,7 @@ public final class CachedIdentity implements Serializable { private final boolean programmatic; private final String name; private final transient SecurityIdentity securityIdentity; + private final Set roles; /** * Creates a new instance based on the given mechanismName and securityIdentity. @@ -64,11 +68,36 @@ public CachedIdentity(String mechanismName, boolean programmatic, Principal prin this(mechanismName, programmatic, null, principal); } + /** + * Creates a new instance based on the given mechanismName and principal. + * + * @param mechanismName the name of the authentication mechanism used to authenticate/authorize the identity + * @param programmatic indicates if this identity was created as a result of programmatic authentication + * @param principal the principal of this cached identity + * @param roles the roles assigned to this cached identity + */ + public CachedIdentity(String mechanismName, boolean programmatic, Principal principal, Set roles) { + this(mechanismName, programmatic, null, principal, roles); + } + private CachedIdentity(String mechanismName, boolean programmatic, SecurityIdentity securityIdentity, Principal principal) { this.mechanismName = checkNotNullParam("mechanismName", mechanismName); this.programmatic = programmatic; this.name = checkNotNullParam("name", checkNotNullParam("principal", principal).getName()); this.securityIdentity = securityIdentity; + if (securityIdentity != null && securityIdentity.getPrincipal() != null) { + this.roles = Roles.toSet(securityIdentity.getRoles()); + } else { + this.roles = Collections.emptySet(); + } + } + + private CachedIdentity(String mechanismName, boolean programmatic, SecurityIdentity securityIdentity, Principal principal, Set roles) { + this.mechanismName = checkNotNullParam("mechanismName", mechanismName); + this.programmatic = programmatic; + this.name = checkNotNullParam("name", checkNotNullParam("principal", principal).getName()); + this.securityIdentity = securityIdentity; + this.roles = roles; } /** @@ -107,6 +136,19 @@ public boolean isProgrammatic() { return programmatic; } + /** + * Returns the roles associated with the cached identity. + * + * @return the roles associated with the cached identity. + */ + public Set getRoles() { + if (this.securityIdentity != null) { + return Roles.toSet(this.securityIdentity.getRoles()); + } else { + return this.roles; + } + } + @Override public String toString() { return "CachedIdentity{" + mechanismName + ", '" + name + "', " + securityIdentity + ", " + programmatic + "}"; diff --git a/tests/base/src/test/java/org/wildfly/security/http/impl/AbstractBaseHttpTest.java b/tests/base/src/test/java/org/wildfly/security/http/impl/AbstractBaseHttpTest.java index 73171b4fb48..52c7bde6181 100644 --- a/tests/base/src/test/java/org/wildfly/security/http/impl/AbstractBaseHttpTest.java +++ b/tests/base/src/test/java/org/wildfly/security/http/impl/AbstractBaseHttpTest.java @@ -61,6 +61,7 @@ import org.wildfly.security.auth.callback.EvidenceVerifyCallback; import org.wildfly.security.auth.callback.IdentityCredentialCallback; import org.wildfly.security.auth.server.SecurityIdentity; +import org.wildfly.security.authz.Roles; import org.wildfly.security.credential.Credential; import org.wildfly.security.credential.PasswordCredential; import org.wildfly.security.evidence.PasswordGuessEvidence; @@ -112,6 +113,10 @@ protected SecurityIdentity mockSecurityIdentity(Principal p) { public Principal getPrincipal() { return p; } + @Mock + public Roles getRoles() { + return Roles.NONE; + } }.getMockInstance(); }