{"action":"closed","issue":{"url":"https://api.github.com/repos/spring-projects/spring-security/issues/4029","repository_url":"https://api.github.com/repos/spring-projects/spring-security","labels_url":"https://api.github.com/repos/spring-projects/spring-security/issues/4029/labels{/name}","comments_url":"https://api.github.com/repos/spring-projects/spring-security/issues/4029/comments","events_url":"https://api.github.com/repos/spring-projects/spring-security/issues/4029/events","html_url":"https://github.com/spring-projects/spring-security/issues/4029","id":171893756,"number":4029,"title":"LdapUserDetails must extend CredentialsContainer","user":{"login":"jbaris","id":819587,"avatar_url":"https://avatars.githubusercontent.com/u/819587?v=3","gravatar_id":"","url":"https://api.github.com/users/jbaris","html_url":"https://github.com/jbaris","followers_url":"https://api.github.com/users/jbaris/followers","following_url":"https://api.github.com/users/jbaris/following{/other_user}","gists_url":"https://api.github.com/users/jbaris/gists{/gist_id}","starred_url":"https://api.github.com/users/jbaris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jbaris/subscriptions","organizations_url":"https://api.github.com/users/jbaris/orgs","repos_url":"https://api.github.com/users/jbaris/repos","events_url":"https://api.github.com/users/jbaris/events{/privacy}","received_events_url":"https://api.github.com/users/jbaris/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-08-18T12:53:42Z","updated_at":"2016-08-19T16:31:59Z","closed_at":"2016-08-19T16:31:59Z","body":"### Summary\r\n\r\nI think LdapUserDetails must extend CredentialsContainer to allow erase credentials. This behavior is similar to org.springframework.security.core.userdetails.User class. When erase-credentials is true (default value), the ProviderManager executes:\r\n```\r\n\t\t\tif (eraseCredentialsAfterAuthentication\r\n\t\t\t\t\t&& (result instanceof CredentialsContainer)) {\r\n\t\t\t\t// Authentication is complete. Remove credentials and other secret data\r\n\t\t\t\t// from authentication\r\n\t\t\t\t((CredentialsContainer) result).eraseCredentials();\r\n\t\t\t}\r\n```\r\nresult is an AbstractAuthenticationToken with:\r\n```\r\n\tpublic void eraseCredentials() {\r\n\t\teraseSecret(getCredentials());\r\n\t\teraseSecret(getPrincipal());\r\n\t\teraseSecret(details);\r\n\t}\r\n\tprivate void eraseSecret(Object secret) {\r\n\t\tif (secret instanceof CredentialsContainer) {\r\n\t\t\t((CredentialsContainer) secret).eraseCredentials();\r\n\t\t}\r\n\t}\r\n```\r\nSo, when principal is an LdapUserDetailsImpl, it must clear its password:\r\n```\r\npublic class LdapUserDetailsImpl implements LdapUserDetails, PasswordPolicyData {\r\n\t...\t\r\n\tpublic void eraseCredentials() {\r\n\t\tpassword = null;\r\n\t}\r\n\t...\r\n}\r\npublic interface LdapUserDetails extends UserDetails, CredentialsContainer {\r\n\t...\r\n}\r\n```\r\n\r\n\r\n### Actual Behavior\r\n\r\n`public interface LdapUserDetails extends UserDetails {`\r\n\r\n### Expected Behavior\r\n\r\n`public interface LdapUserDetails extends UserDetails, CredentialsContainer {`\r\n\r\n### Version\r\n\r\n4.1.1.RELEASE\r\n"}}
{"actor":{"display_login":"jgrandja"}}