mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-02-24 07:37:50 +00:00
SEC-1325: Tighten up Authentication interface contract to disallow null authorities. Modified internals of AbstractAuthenticationToken to use an empty list instead of null. Clarified Javadoc. removed unnecessary null checks in classes which use the interface.
This commit is contained in:
parent
ef3d9c7877
commit
cad32ffe39
@ -68,8 +68,7 @@ public class MethodInvocationPrivilegeEvaluator implements InitializingBean {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((authentication == null) || (authentication.getAuthorities() == null)
|
||||
|| (authentication.getAuthorities().isEmpty())) {
|
||||
if (authentication == null || authentication.getAuthorities().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ import java.util.Collections;
|
||||
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
|
||||
@ -46,19 +47,17 @@ public abstract class AbstractAuthenticationToken implements Authentication {
|
||||
/**
|
||||
* Creates a token with the supplied array of authorities.
|
||||
*
|
||||
* @param authorities the list of <tt>GrantedAuthority</tt>s for the
|
||||
* principal represented by this authentication object. A
|
||||
* <code>null</code> value indicates that no authorities have been
|
||||
* granted (pursuant to the interface contract specified by {@link
|
||||
* Authentication#getAuthorities()}<code>null</code> should only be
|
||||
* presented if the principal has not been authenticated).
|
||||
* @param authorities the collection of <tt>GrantedAuthority</tt>s for the
|
||||
* principal represented by this authentication object.
|
||||
*/
|
||||
public AbstractAuthenticationToken(Collection<GrantedAuthority> authorities) {
|
||||
if (authorities == null) {
|
||||
this.authorities = null;
|
||||
} else {
|
||||
this.authorities = AuthorityUtils.NO_AUTHORITIES;
|
||||
return;
|
||||
}
|
||||
|
||||
for (GrantedAuthority a: authorities) {
|
||||
if(a == null) {
|
||||
if (a == null) {
|
||||
throw new IllegalArgumentException("Authorities collection cannot contain any null elements");
|
||||
}
|
||||
}
|
||||
@ -66,7 +65,6 @@ public abstract class AbstractAuthenticationToken implements Authentication {
|
||||
temp.addAll(authorities);
|
||||
this.authorities = Collections.unmodifiableList(temp);
|
||||
}
|
||||
}
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
@ -77,15 +75,9 @@ public abstract class AbstractAuthenticationToken implements Authentication {
|
||||
|
||||
AbstractAuthenticationToken test = (AbstractAuthenticationToken) obj;
|
||||
|
||||
if (!(authorities == null && test.authorities == null)) {
|
||||
// Not both null
|
||||
if (authorities == null || test.authorities == null) {
|
||||
if (!authorities.equals(test.authorities)) {
|
||||
return false;
|
||||
}
|
||||
if(!authorities.equals(test.authorities)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((this.details == null) && (test.getDetails() != null)) {
|
||||
return false;
|
||||
@ -141,11 +133,9 @@ public abstract class AbstractAuthenticationToken implements Authentication {
|
||||
public int hashCode() {
|
||||
int code = 31;
|
||||
|
||||
if (authorities != null) {
|
||||
for (GrantedAuthority authority : authorities) {
|
||||
code ^= authority.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getPrincipal() != null) {
|
||||
code ^= this.getPrincipal().hashCode();
|
||||
@ -179,14 +169,14 @@ public abstract class AbstractAuthenticationToken implements Authentication {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(super.toString()).append(": ");
|
||||
sb.append("Principal: ").append(this.getPrincipal()).append("; ");
|
||||
sb.append("Password: [PROTECTED]; ");
|
||||
sb.append("Authenticated: ").append(this.isAuthenticated()).append("; ");
|
||||
sb.append("Details: ").append(this.getDetails()).append("; ");
|
||||
|
||||
if (authorities != null) {
|
||||
if (!authorities.isEmpty()) {
|
||||
sb.append("Granted Authorities: ");
|
||||
|
||||
int i = 0;
|
||||
|
@ -185,10 +185,7 @@ public class JaasAuthenticationProvider implements AuthenticationProvider, Appli
|
||||
|
||||
// Create a set to hold the authorities, and add any that have already been applied.
|
||||
authorities = new HashSet<GrantedAuthority>();
|
||||
|
||||
if (request.getAuthorities() != null) {
|
||||
authorities.addAll(request.getAuthorities());
|
||||
}
|
||||
|
||||
// Get the subject principals and pass them to each of the AuthorityGranters
|
||||
Set<Principal> principals = loginContext.getSubject().getPrincipals();
|
||||
|
@ -51,10 +51,14 @@ public interface Authentication extends Principal, Serializable {
|
||||
/**
|
||||
* Set by an <code>AuthenticationManager</code> to indicate the authorities that the principal has been
|
||||
* granted. Note that classes should not rely on this value as being valid unless it has been set by a trusted
|
||||
* <code>AuthenticationManager</code>.<p>Implementations should ensure that modifications to the returned
|
||||
* array do not affect the state of the Authentication object (e.g. by returning an array copy).</p>
|
||||
* <code>AuthenticationManager</code>.
|
||||
* <p>
|
||||
* Implementations should ensure that modifications to the returned collection
|
||||
* array do not affect the state of the Authentication object, or use an unmodifiable instance.
|
||||
* </p>
|
||||
*
|
||||
* @return the authorities granted to the principal, or <code>null</code> if authentication has not been completed
|
||||
* @return the authorities granted to the principal, or an empty collection if the token has not been authenticated.
|
||||
* Never null.
|
||||
*/
|
||||
Collection<GrantedAuthority> getAuthorities();
|
||||
|
||||
|
@ -74,7 +74,7 @@ public class User implements UserDetails {
|
||||
* locked
|
||||
* @param authorities the authorities that should be granted to the caller
|
||||
* if they presented the correct username and password and the user
|
||||
* is enabled
|
||||
* is enabled. Not null.
|
||||
*
|
||||
* @throws IllegalArgumentException if a <code>null</code> value was passed
|
||||
* either as a parameter or as an element in the
|
||||
@ -210,7 +210,7 @@ public class User implements UserDetails {
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(super.toString()).append(": ");
|
||||
sb.append("Username: ").append(this.username).append("; ");
|
||||
sb.append("Password: [PROTECTED]; ");
|
||||
@ -219,7 +219,7 @@ public class User implements UserDetails {
|
||||
sb.append("credentialsNonExpired: ").append(this.credentialsNonExpired).append("; ");
|
||||
sb.append("AccountNonLocked: ").append(this.accountNonLocked).append("; ");
|
||||
|
||||
if (this.getAuthorities() != null) {
|
||||
if (!authorities.isEmpty()) {
|
||||
sb.append("Granted Authorities: ");
|
||||
|
||||
boolean first = true;
|
||||
|
@ -17,6 +17,8 @@ package org.springframework.security.ldap.userdetails;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.naming.Name;
|
||||
|
||||
@ -140,7 +142,7 @@ public class LdapUserDetailsImpl implements LdapUserDetails, PasswordPolicyData
|
||||
*/
|
||||
public static class Essence {
|
||||
protected LdapUserDetailsImpl instance = createTarget();
|
||||
private Collection<GrantedAuthority> mutableAuthorities = new ArrayList<GrantedAuthority>();
|
||||
private List<GrantedAuthority> mutableAuthorities = new ArrayList<GrantedAuthority>();
|
||||
|
||||
public Essence() { }
|
||||
|
||||
@ -184,7 +186,7 @@ public class LdapUserDetailsImpl implements LdapUserDetails, PasswordPolicyData
|
||||
Assert.notNull(instance.username, "username must not be null");
|
||||
Assert.notNull(instance.getDn(), "Distinguished name must not be null");
|
||||
|
||||
instance.authorities = getGrantedAuthorities();
|
||||
instance.authorities = Collections.unmodifiableList(mutableAuthorities);
|
||||
|
||||
LdapUserDetails newInstance = instance;
|
||||
|
||||
@ -206,7 +208,8 @@ public class LdapUserDetailsImpl implements LdapUserDetails, PasswordPolicyData
|
||||
}
|
||||
|
||||
public void setAuthorities(Collection<GrantedAuthority> authorities) {
|
||||
mutableAuthorities = authorities;
|
||||
mutableAuthorities = new ArrayList<GrantedAuthority>();
|
||||
mutableAuthorities.addAll(authorities);
|
||||
}
|
||||
|
||||
public void setCredentialsNonExpired(boolean credentialsNonExpired) {
|
||||
|
@ -125,10 +125,6 @@ public class LegacyAuthorizeTag extends TagSupport {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if ((null == currentUser.getAuthorities())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return currentUser.getAuthorities();
|
||||
}
|
||||
|
||||
|
@ -130,8 +130,7 @@ public class DefaultWebInvocationPrivilegeEvaluator implements WebInvocationPriv
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((authentication == null) || (authentication.getAuthorities() == null)
|
||||
|| authentication.getAuthorities().isEmpty()) {
|
||||
if (authentication == null || authentication.getAuthorities().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ public class PreAuthenticatedAuthenticationTokenTests extends TestCase {
|
||||
assertEquals(principal, token.getPrincipal());
|
||||
assertEquals(credentials, token.getCredentials());
|
||||
assertEquals(details, token.getDetails());
|
||||
assertNull(token.getAuthorities());
|
||||
assertTrue(token.getAuthorities().isEmpty());
|
||||
}
|
||||
|
||||
public void testPreAuthenticatedAuthenticationTokenRequestWithoutDetails() {
|
||||
@ -35,7 +35,7 @@ public class PreAuthenticatedAuthenticationTokenTests extends TestCase {
|
||||
assertEquals(principal, token.getPrincipal());
|
||||
assertEquals(credentials, token.getCredentials());
|
||||
assertNull(token.getDetails());
|
||||
assertNull(token.getAuthorities());
|
||||
assertTrue(token.getAuthorities().isEmpty());
|
||||
}
|
||||
|
||||
public void testPreAuthenticatedAuthenticationTokenResponse() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user