diff --git a/core/src/main/java/org/acegisecurity/userdetails/User.java b/core/src/main/java/org/acegisecurity/userdetails/User.java
index 64c7333c51..4400c0ab06 100644
--- a/core/src/main/java/org/acegisecurity/userdetails/User.java
+++ b/core/src/main/java/org/acegisecurity/userdetails/User.java
@@ -185,6 +185,29 @@ public class User implements UserDetails {
}
public String toString() {
- return username;
+ StringBuffer sb = new StringBuffer();
+ sb.append(super.toString() + ": ");
+ sb.append("Username: " + this.username + "; ");
+ sb.append("Password: [PROTECTED]; ");
+ sb.append("Enabled: " + this.enabled + "; ");
+ sb.append("AccountNonExpired: " + this.accountNonExpired + "; ");
+ sb.append("credentialsNonExpired: " + this.credentialsNonExpired + "; ");
+ sb.append("AccountNonLocked: " + this.accountNonLocked + "; ");
+
+ if (this.getAuthorities() != null) {
+ sb.append("Granted Authorities: ");
+
+ for (int i = 0; i < this.getAuthorities().length; i++) {
+ if (i > 0) {
+ sb.append(", ");
+ }
+
+ sb.append(this.getAuthorities()[i].toString());
+ }
+ } else {
+ sb.append("Not granted any authorities");
+ }
+
+ return sb.toString();
}
}
diff --git a/core/src/test/java/org/acegisecurity/providers/dao/UserTests.java b/core/src/test/java/org/acegisecurity/providers/dao/UserTests.java
index fa0ea6b442..895dc1c7d0 100644
--- a/core/src/test/java/org/acegisecurity/providers/dao/UserTests.java
+++ b/core/src/test/java/org/acegisecurity/providers/dao/UserTests.java
@@ -120,6 +120,7 @@ public class UserTests extends TestCase {
user.getAuthorities()[0]);
assertEquals(new GrantedAuthorityImpl("ROLE_TWO"),
user.getAuthorities()[1]);
+ assertTrue(user.toString().indexOf("marissa") != -1);
}
public void testUserIsEnabled() throws Exception {
diff --git a/doc/xdocs/changes.xml b/doc/xdocs/changes.xml
index afa26c8d15..2fdf5eaf8e 100644
--- a/doc/xdocs/changes.xml
+++ b/doc/xdocs/changes.xml
@@ -30,6 +30,7 @@
UserDetails now advises locked accounts, with corresponding DaoAuthenticationProvider events and enforcement
ContextHolderAwareRequestWrapper methods returns null if user is anonymous
AbstractBasicAclEntry improved compatibility with Hibernate
+ User now provides a more useful toString() method
SecurityEnforcementFilter caused NullPointerException when anonymous authentication used with BasicProcessingFilterEntryPoint
FilterChainProxy now supports replacement of ServletRequest and ServetResponse by Filter beans
Corrected Authz parsing of whitespace in GrantedAuthoritys