diff --git a/core/src/main/java/org/acegisecurity/providers/AbstractAuthenticationToken.java b/core/src/main/java/org/acegisecurity/providers/AbstractAuthenticationToken.java
index f46c867642..0e28688f40 100644
--- a/core/src/main/java/org/acegisecurity/providers/AbstractAuthenticationToken.java
+++ b/core/src/main/java/org/acegisecurity/providers/AbstractAuthenticationToken.java
@@ -1,4 +1,4 @@
-/* Copyright 2004, 2005 Acegi Technology Pty Limited
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.acegisecurity.providers;
import org.acegisecurity.Authentication;
+
import org.acegisecurity.userdetails.UserDetails;
@@ -28,24 +29,6 @@ import org.acegisecurity.userdetails.UserDetails;
public abstract class AbstractAuthenticationToken implements Authentication {
//~ Methods ================================================================
- /**
- * Subclasses should override if they wish to provide additional details
- * about the authentication event.
- *
- * @return always null
- */
- public Object getDetails() {
- return null;
- }
-
- public String getName() {
- if (this.getPrincipal() instanceof UserDetails) {
- return ((UserDetails) this.getPrincipal()).getUsername();
- }
-
- return this.getPrincipal().toString();
- }
-
public boolean equals(Object obj) {
if (obj instanceof AbstractAuthenticationToken) {
AbstractAuthenticationToken test = (AbstractAuthenticationToken) obj;
@@ -77,6 +60,48 @@ public abstract class AbstractAuthenticationToken implements Authentication {
return false;
}
+ /**
+ * Subclasses should override if they wish to provide additional details
+ * about the authentication event.
+ *
+ * @return always null
+ */
+ public Object getDetails() {
+ return null;
+ }
+
+ public String getName() {
+ if (this.getPrincipal() instanceof UserDetails) {
+ return ((UserDetails) this.getPrincipal()).getUsername();
+ }
+
+ return this.getPrincipal().toString();
+ }
+
+ public int hashCode() {
+ int code = 2305;
+
+ if (this.getAuthorities() != null) {
+ for (int i = 0; i < this.getAuthorities().length; i++) {
+ code = code * (this.getAuthorities()[i].hashCode() % 7);
+ }
+ }
+
+ if (this.getPrincipal() != null) {
+ code = code * (this.getPrincipal().hashCode() % 7);
+ }
+
+ if (this.getCredentials() != null) {
+ code = code * (this.getCredentials().hashCode() % 7);
+ }
+
+ if (this.isAuthenticated()) {
+ code = code * -1;
+ }
+
+ return code;
+ }
+
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(super.toString()).append(": ");
diff --git a/core/src/test/java/org/acegisecurity/providers/AbstractAuthenticationTokenTests.java b/core/src/test/java/org/acegisecurity/providers/AbstractAuthenticationTokenTests.java
index 44f94770dd..e782b42c9b 100644
--- a/core/src/test/java/org/acegisecurity/providers/AbstractAuthenticationTokenTests.java
+++ b/core/src/test/java/org/acegisecurity/providers/AbstractAuthenticationTokenTests.java
@@ -1,4 +1,4 @@
-/* Copyright 2004 Acegi Technology Pty Limited
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,14 +40,14 @@ public class AbstractAuthenticationTokenTests extends TestCase {
//~ Methods ================================================================
- public final void setUp() throws Exception {
- super.setUp();
- }
-
public static void main(String[] args) {
junit.textui.TestRunner.run(AbstractAuthenticationTokenTests.class);
}
+ public final void setUp() throws Exception {
+ super.setUp();
+ }
+
public void testGetters() throws Exception {
MockAuthenticationImpl token = new MockAuthenticationImpl("Test",
"Password",
@@ -58,6 +58,25 @@ public class AbstractAuthenticationTokenTests extends TestCase {
assertEquals("Test", token.getName());
}
+ public void testHashCode() throws Exception {
+ MockAuthenticationImpl token1 = new MockAuthenticationImpl("Test",
+ "Password",
+ new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
+ "ROLE_TWO")});
+ MockAuthenticationImpl token2 = new MockAuthenticationImpl("Test",
+ "Password",
+ new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_ONE"), new GrantedAuthorityImpl(
+ "ROLE_TWO")});
+ MockAuthenticationImpl token3 = new MockAuthenticationImpl(null, null,
+ new GrantedAuthority[] {});
+ assertEquals(token1.hashCode(), token2.hashCode());
+ assertTrue(token1.hashCode() != token3.hashCode());
+
+ token2.setAuthenticated(true);
+
+ assertTrue(token1.hashCode() != token2.hashCode());
+ }
+
public void testObjectsEquals() throws Exception {
MockAuthenticationImpl token1 = new MockAuthenticationImpl("Test",
"Password",
@@ -143,14 +162,6 @@ public class AbstractAuthenticationTokenTests extends TestCase {
super();
}
- public void setAuthenticated(boolean isAuthenticated) {
- this.authenticated = isAuthenticated;
- }
-
- public boolean isAuthenticated() {
- return this.authenticated;
- }
-
public GrantedAuthority[] getAuthorities() {
return this.authorities;
}
@@ -162,5 +173,13 @@ public class AbstractAuthenticationTokenTests extends TestCase {
public Object getPrincipal() {
return this.principal;
}
+
+ public boolean isAuthenticated() {
+ return this.authenticated;
+ }
+
+ public void setAuthenticated(boolean isAuthenticated) {
+ this.authenticated = isAuthenticated;
+ }
}
}